]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Merge branch 'master' of https://github.com/minetest/minetest
authorElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 17 May 2022 20:12:00 +0000 (22:12 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 17 May 2022 20:12:00 +0000 (22:12 +0200)
534 files changed:
.clang-format
.github/workflows/android.yml
.github/workflows/build.yml
.github/workflows/cpp_lint.yml
.github/workflows/lua.yml [new file with mode: 0644]
.github/workflows/lua_lint.yml [deleted file]
.github/workflows/macos.yml
.gitignore
.gitlab-ci.yml
CMakeLists.txt
Dockerfile
README.md
android/app/build.gradle
android/app/src/main/AndroidManifest.xml
android/app/src/main/java/net/minetest/minetest/CopyZipTask.java [deleted file]
android/app/src/main/java/net/minetest/minetest/GameActivity.java
android/app/src/main/java/net/minetest/minetest/MainActivity.java
android/app/src/main/java/net/minetest/minetest/UnzipService.java
android/app/src/main/java/net/minetest/minetest/Utils.java [new file with mode: 0644]
android/app/src/main/res/layout/activity_main.xml
android/app/src/main/res/values/strings.xml
android/build.gradle
android/gradle/wrapper/gradle-wrapper.properties
android/gradlew
android/native/build.gradle
android/native/jni/Android.mk
android/native/jni/Application.mk
builtin/async/game.lua [new file with mode: 0644]
builtin/async/init.lua [deleted file]
builtin/async/mainmenu.lua [new file with mode: 0644]
builtin/client/register.lua
builtin/common/after.lua
builtin/common/chatcommands.lua
builtin/common/information_formspecs.lua
builtin/common/misc_helpers.lua
builtin/common/strict.lua
builtin/common/tests/misc_helpers_spec.lua
builtin/common/tests/serialize_spec.lua
builtin/common/tests/vector_spec.lua
builtin/common/vector.lua
builtin/fstk/ui.lua
builtin/game/async.lua [new file with mode: 0644]
builtin/game/chat.lua
builtin/game/features.lua
builtin/game/init.lua
builtin/game/item.lua
builtin/game/item_entity.lua
builtin/game/item_s.lua [new file with mode: 0644]
builtin/game/misc.lua
builtin/game/misc_s.lua [new file with mode: 0644]
builtin/game/privileges.lua
builtin/game/register.lua
builtin/game/statbars.lua
builtin/init.lua
builtin/locale/__builtin.de.tr
builtin/locale/__builtin.it.tr
builtin/locale/template.txt
builtin/mainmenu/common.lua
builtin/mainmenu/dlg_config_world.lua
builtin/mainmenu/dlg_contentstore.lua
builtin/mainmenu/dlg_create_world.lua
builtin/mainmenu/dlg_settings_advanced.lua
builtin/mainmenu/game_theme.lua [new file with mode: 0644]
builtin/mainmenu/generate_from_settingtypes.lua
builtin/mainmenu/init.lua
builtin/mainmenu/pkgmgr.lua
builtin/mainmenu/tab_about.lua
builtin/mainmenu/tab_content.lua
builtin/mainmenu/tab_local.lua
builtin/mainmenu/tab_settings.lua
builtin/mainmenu/tests/serverlistmgr_spec.lua
builtin/mainmenu/textures.lua [deleted file]
builtin/profiler/instrumentation.lua
builtin/settingtypes.txt
client/shaders/nodes_shader/opengl_fragment.glsl
client/shaders/nodes_shader/opengl_vertex.glsl
client/shaders/object_shader/opengl_fragment.glsl
client/shaders/object_shader/opengl_vertex.glsl
client/shaders/shadow_shaders/pass1_trans_fragment.glsl
client/shaders/shadow_shaders/pass1_trans_vertex.glsl
client/shaders/shadow_shaders/pass1_vertex.glsl
clientmods/preview/mod.conf
cmake/Modules/FindOpenGLES2.cmake [deleted file]
cmake/Modules/FindSQLite3.cmake
cmake/Modules/FindVorbis.cmake
doc/Doxyfile.in
doc/breakages.md [new file with mode: 0644]
doc/client_lua_api.txt
doc/lgpl-2.1.txt
doc/lua_api.txt
doc/menu_lua_api.txt
doc/minetest.6
doc/texture_packs.txt
doc/world_format.txt
fonts/mono_dejavu_sans_10.xml [deleted file]
fonts/mono_dejavu_sans_100.png [deleted file]
fonts/mono_dejavu_sans_11.xml [deleted file]
fonts/mono_dejavu_sans_110.png [deleted file]
fonts/mono_dejavu_sans_12.xml [deleted file]
fonts/mono_dejavu_sans_120.png [deleted file]
fonts/mono_dejavu_sans_14.xml [deleted file]
fonts/mono_dejavu_sans_140.png [deleted file]
fonts/mono_dejavu_sans_16.xml [deleted file]
fonts/mono_dejavu_sans_160.png [deleted file]
fonts/mono_dejavu_sans_18.xml [deleted file]
fonts/mono_dejavu_sans_180.png [deleted file]
fonts/mono_dejavu_sans_20.xml [deleted file]
fonts/mono_dejavu_sans_200.png [deleted file]
fonts/mono_dejavu_sans_22.xml [deleted file]
fonts/mono_dejavu_sans_220.png [deleted file]
fonts/mono_dejavu_sans_24.xml [deleted file]
fonts/mono_dejavu_sans_240.png [deleted file]
fonts/mono_dejavu_sans_26.xml [deleted file]
fonts/mono_dejavu_sans_260.png [deleted file]
fonts/mono_dejavu_sans_28.xml [deleted file]
fonts/mono_dejavu_sans_280.png [deleted file]
fonts/mono_dejavu_sans_4.xml [deleted file]
fonts/mono_dejavu_sans_40.png [deleted file]
fonts/mono_dejavu_sans_6.xml [deleted file]
fonts/mono_dejavu_sans_60.png [deleted file]
fonts/mono_dejavu_sans_8.xml [deleted file]
fonts/mono_dejavu_sans_80.png [deleted file]
fonts/mono_dejavu_sans_9.xml [deleted file]
fonts/mono_dejavu_sans_90.png [deleted file]
games/devtest/.luacheckrc [new file with mode: 0644]
games/devtest/mods/basetools/init.lua
games/devtest/mods/basetools/textures/basetools_bloodsword.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_dirtpick.png [deleted file]
games/devtest/mods/basetools/textures/basetools_elementalsword.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_firesword.png
games/devtest/mods/basetools/textures/basetools_healdagger.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_healsword.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_icesword.png
games/devtest/mods/basetools/textures/basetools_mesepick.png
games/devtest/mods/basetools/textures/basetools_mesesword.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_superhealsword.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_titaniumsword.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_usespick.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_usessword.png [new file with mode: 0644]
games/devtest/mods/basetools/textures/basetools_wooddagger.png [new file with mode: 0644]
games/devtest/mods/broken/init.lua [new file with mode: 0644]
games/devtest/mods/broken/mod.conf [new file with mode: 0644]
games/devtest/mods/testentities/armor.lua
games/devtest/mods/testentities/textures/testentities_armorball.png
games/devtest/mods/testformspec/formspec.lua
games/devtest/mods/testnodes/liquids.lua
games/devtest/mods/testnodes/properties.lua
games/devtest/mods/testnodes/textures.lua
games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_move_resistance.png [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga [new file with mode: 0644]
games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga [new file with mode: 0644]
games/devtest/mods/unittests/async_env.lua [new file with mode: 0644]
games/devtest/mods/unittests/crafting.lua
games/devtest/mods/unittests/crafting_prepare.lua
games/devtest/mods/unittests/init.lua
games/devtest/mods/unittests/inside_async_env.lua [new file with mode: 0644]
games/devtest/mods/unittests/itemdescription.lua
games/devtest/mods/unittests/misc.lua [new file with mode: 0644]
games/devtest/mods/unittests/player.lua
games/devtest/mods/unittests/random.lua [deleted file]
games/devtest/mods/unittests/textures/unittests_description_test.png [new file with mode: 0644]
games/devtest/mods/util_commands/init.lua
lib/bitop/CMakeLists.txt [new file with mode: 0644]
lib/bitop/bit.c [new file with mode: 0644]
lib/bitop/bit.h [new file with mode: 0644]
lib/catch2/CMakeLists.txt [new file with mode: 0644]
lib/catch2/catch.hpp [new file with mode: 0644]
lib/gmp/CMakeLists.txt
lib/jsoncpp/CMakeLists.txt
lib/lua/CMakeLists.txt
lib/lua/src/CMakeLists.txt
lib/lua/src/luaconf.h
minetest.conf.example
misc/net.minetest.minetest.appdata.xml
mods/mods_here.txt
po/ar/minetest.po
po/be/minetest.po
po/bg/minetest.po
po/ca/minetest.po
po/cs/minetest.po
po/da/minetest.po
po/de/minetest.po
po/dv/minetest.po
po/el/minetest.po
po/eo/minetest.po
po/es/minetest.po
po/et/minetest.po
po/eu/minetest.po
po/fi/minetest.po
po/fil/minetest.po
po/fr/minetest.po
po/gd/minetest.po
po/gl/minetest.po
po/he/minetest.po
po/hi/minetest.po
po/hu/minetest.po
po/id/minetest.po
po/it/minetest.po
po/ja/minetest.po
po/jbo/minetest.po
po/kk/minetest.po
po/kn/minetest.po
po/ko/minetest.po
po/ky/minetest.po
po/lt/minetest.po
po/lv/minetest.po
po/lzh/minetest.po [new file with mode: 0644]
po/minetest.pot
po/mr/minetest.po
po/ms/minetest.po
po/ms_Arab/minetest.po
po/nb/minetest.po
po/nl/minetest.po
po/nn/minetest.po
po/pl/minetest.po
po/pt/minetest.po
po/pt_BR/minetest.po
po/ro/minetest.po
po/ru/minetest.po
po/sk/minetest.po
po/sl/minetest.po
po/sr_Cyrl/minetest.po
po/sr_Latn/minetest.po
po/sv/minetest.po
po/sw/minetest.po
po/th/minetest.po
po/tr/minetest.po
po/tt/minetest.po
po/uk/minetest.po
po/vi/minetest.po
po/yue/minetest.po [new file with mode: 0644]
po/zh_CN/minetest.po
po/zh_TW/minetest.po
src/CMakeLists.txt
src/benchmark/CMakeLists.txt [new file with mode: 0644]
src/benchmark/benchmark.cpp [new file with mode: 0644]
src/benchmark/benchmark.h [new file with mode: 0644]
src/benchmark/benchmark_serialize.cpp [new file with mode: 0644]
src/benchmark/benchmark_setup.h [new file with mode: 0644]
src/chat.cpp
src/chat.h
src/client/CMakeLists.txt
src/client/camera.cpp
src/client/camera.h
src/client/client.cpp
src/client/client.h
src/client/clientenvironment.cpp
src/client/clientlauncher.cpp
src/client/clientmap.cpp
src/client/clientmap.h
src/client/clientmedia.h
src/client/clouds.h
src/client/content_cao.cpp
src/client/content_cao.h
src/client/content_mapblock.cpp
src/client/content_mapblock.h
src/client/fontengine.cpp
src/client/fontengine.h
src/client/game.cpp
src/client/game.h
src/client/gameui.cpp
src/client/gameui.h
src/client/guiscalingfilter.cpp
src/client/hud.cpp
src/client/imagefilters.cpp
src/client/inputhandler.h
src/client/joystick_controller.cpp
src/client/localplayer.cpp
src/client/localplayer.h
src/client/mapblock_mesh.cpp
src/client/mapblock_mesh.h
src/client/mesh.cpp
src/client/mesh.h
src/client/mesh_generator_thread.cpp
src/client/mesh_generator_thread.h
src/client/minimap.cpp
src/client/render/anaglyph.cpp
src/client/render/core.cpp
src/client/renderingengine.cpp
src/client/shader.cpp
src/client/shadows/dynamicshadows.cpp
src/client/shadows/dynamicshadows.h
src/client/shadows/dynamicshadowsrender.cpp
src/client/shadows/dynamicshadowsrender.h
src/client/shadows/shadowsshadercallbacks.cpp
src/client/shadows/shadowsshadercallbacks.h
src/client/sky.cpp
src/client/sky.h
src/client/tile.cpp
src/client/tile.h
src/client/wieldmesh.cpp
src/clientiface.cpp
src/clientiface.h
src/cloudparams.h [deleted file]
src/cmake_config.h.in
src/collision.cpp
src/config.h
src/constants.h
src/content/mods.cpp
src/content/mods.h
src/content/subgames.cpp
src/content/subgames.h
src/craftdef.cpp
src/database/database-dummy.cpp
src/database/database-dummy.h
src/database/database-files.cpp
src/database/database-files.h
src/database/database-leveldb.cpp
src/database/database-postgresql.cpp
src/database/database-postgresql.h
src/database/database-sqlite3.cpp
src/database/database-sqlite3.h
src/database/database.h
src/defaultsettings.cpp
src/emerge.cpp
src/emerge.h
src/environment.cpp
src/filesys.cpp
src/filesys.h
src/gamedef.h
src/gettext.h
src/gettime.h
src/gui/CMakeLists.txt
src/gui/cheatMenu.cpp
src/gui/guiBackgroundImage.cpp
src/gui/guiButton.cpp
src/gui/guiButton.h
src/gui/guiChatConsole.cpp
src/gui/guiConfirmRegistration.cpp
src/gui/guiEditBox.cpp
src/gui/guiEditBox.h
src/gui/guiEditBoxWithScrollbar.cpp
src/gui/guiEditBoxWithScrollbar.h
src/gui/guiEngine.cpp
src/gui/guiFormSpecMenu.cpp
src/gui/guiFormSpecMenu.h
src/gui/guiHyperText.cpp
src/gui/guiHyperText.h
src/gui/guiPasswordChange.cpp
src/gui/guiSkin.cpp
src/gui/guiSkin.h
src/gui/guiTable.cpp
src/gui/modalMenu.cpp
src/gui/modalMenu.h
src/gui/profilergraph.cpp
src/gui/touchscreengui.cpp
src/gui/touchscreengui.h
src/httpfetch.cpp
src/httpfetch.h
src/hud.cpp
src/hud.h
src/inventory.cpp
src/inventory.h
src/inventorymanager.cpp
src/irrlicht_changes/CGUITTFont.cpp
src/irrlicht_changes/CMakeLists.txt
src/irrlicht_changes/static_text.cpp
src/irrlicht_changes/static_text.h
src/lighting.h [new file with mode: 0644]
src/log.cpp
src/log.h
src/main.cpp
src/map.cpp
src/map.h
src/map_settings_manager.cpp
src/mapblock.cpp
src/mapblock.h
src/mapgen/dungeongen.cpp
src/mapgen/mapgen.cpp
src/mapgen/mapgen_flat.cpp
src/mapgen/mapgen_v6.cpp
src/mapgen/mapgen_v6.h
src/mapgen/mg_biome.cpp
src/mapgen/mg_ore.cpp
src/modchannels.cpp
src/network/address.cpp
src/network/address.h
src/network/clientopcodes.cpp
src/network/clientpackethandler.cpp
src/network/connection.cpp
src/network/connection.h
src/network/connectionthreads.cpp
src/network/connectionthreads.h
src/network/networkpacket.h
src/network/networkprotocol.h
src/network/serveropcodes.cpp
src/network/serverpackethandler.cpp
src/network/socket.cpp
src/network/socket.h
src/nodedef.cpp
src/nodedef.h
src/noise.cpp
src/noise.h
src/object_properties.cpp
src/player.cpp
src/player.h
src/porting.cpp
src/porting_android.cpp
src/remoteplayer.cpp
src/remoteplayer.h
src/rollback.cpp
src/rollback.h
src/script/common/CMakeLists.txt
src/script/common/c_content.cpp
src/script/common/c_content.h
src/script/common/c_converter.cpp
src/script/common/c_converter.h
src/script/common/c_internal.cpp
src/script/common/c_internal.h
src/script/common/c_packer.cpp [new file with mode: 0644]
src/script/common/c_packer.h [new file with mode: 0644]
src/script/cpp_api/s_async.cpp
src/script/cpp_api/s_async.h
src/script/cpp_api/s_base.cpp
src/script/cpp_api/s_base.h
src/script/cpp_api/s_client.cpp
src/script/cpp_api/s_entity.cpp
src/script/cpp_api/s_entity.h
src/script/cpp_api/s_env.cpp
src/script/cpp_api/s_item.cpp
src/script/cpp_api/s_item.h
src/script/cpp_api/s_node.h
src/script/cpp_api/s_player.cpp
src/script/cpp_api/s_player.h
src/script/cpp_api/s_security.cpp
src/script/cpp_api/s_security.h
src/script/cpp_api/s_server.cpp
src/script/cpp_api/s_server.h
src/script/lua_api/l_areastore.cpp
src/script/lua_api/l_client.cpp
src/script/lua_api/l_craft.cpp
src/script/lua_api/l_craft.h
src/script/lua_api/l_env.cpp
src/script/lua_api/l_env.h
src/script/lua_api/l_http.cpp
src/script/lua_api/l_http.h
src/script/lua_api/l_internal.h
src/script/lua_api/l_inventory.cpp
src/script/lua_api/l_inventory.h
src/script/lua_api/l_item.cpp
src/script/lua_api/l_item.h
src/script/lua_api/l_localplayer.cpp
src/script/lua_api/l_localplayer.h
src/script/lua_api/l_mainmenu.cpp
src/script/lua_api/l_mainmenu.h
src/script/lua_api/l_metadata.cpp
src/script/lua_api/l_nodemeta.cpp
src/script/lua_api/l_noise.cpp
src/script/lua_api/l_noise.h
src/script/lua_api/l_object.cpp
src/script/lua_api/l_object.h
src/script/lua_api/l_server.cpp
src/script/lua_api/l_server.h
src/script/lua_api/l_storage.cpp
src/script/lua_api/l_util.cpp
src/script/lua_api/l_util.h
src/script/lua_api/l_vmanip.cpp
src/script/lua_api/l_vmanip.h
src/script/scripting_server.cpp
src/script/scripting_server.h
src/serialization.cpp
src/server.cpp
src/server.h
src/server/luaentity_sao.cpp
src/server/luaentity_sao.h
src/server/mods.cpp
src/server/player_sao.cpp
src/server/player_sao.h
src/server/serveractiveobject.h
src/server/serverinventorymgr.cpp
src/server/unit_sao.cpp
src/serverenvironment.cpp
src/serverenvironment.h
src/serverlist.cpp
src/settings.cpp
src/settings.h
src/settings_translation_file.cpp
src/skyparams.h
src/terminal_chat_console.cpp
src/threading/thread.cpp
src/tool.cpp
src/tool.h
src/unittest/CMakeLists.txt
src/unittest/test.cpp
src/unittest/test_address.cpp
src/unittest/test_config.h.in
src/unittest/test_connection.cpp
src/unittest/test_eventmanager.cpp
src/unittest/test_gettext.cpp [new file with mode: 0644]
src/unittest/test_irrptr.cpp
src/unittest/test_lua.cpp [new file with mode: 0644]
src/unittest/test_map.cpp [new file with mode: 0644]
src/unittest/test_mod/test_mod/init.lua [new file with mode: 0644]
src/unittest/test_mod/test_mod/mod.conf [new file with mode: 0644]
src/unittest/test_modmetadatadatabase.cpp [new file with mode: 0644]
src/unittest/test_player.cpp [deleted file]
src/unittest/test_server_shutdown_state.cpp
src/unittest/test_servermodmanager.cpp
src/unittest/test_socket.cpp
src/unittest/test_utilities.cpp
src/unittest/test_voxelarea.cpp
src/util/Optional.h
src/util/areastore.cpp
src/util/basic_macros.h
src/util/ieee_float.cpp
src/util/metricsbackend.cpp
src/util/metricsbackend.h
src/util/png.cpp
src/util/pointer.h
src/util/srp.cpp
src/util/stream.h [new file with mode: 0644]
src/util/string.cpp
src/util/string.h
src/version.cpp
textures/base/pack/no_texture.png [new file with mode: 0644]
util/buildbot/buildwin32.sh
util/buildbot/buildwin64.sh
util/ci/build.sh
util/ci/build_prometheus_cpp.sh
util/ci/clang-tidy.sh
util/ci/common.sh
util/generate-texture-normals.sh [deleted file]
util/test_multiplayer.sh
util/updatepo.sh
util/wireshark/minetest.lua

index 0db8ab1671aac78b3d93144dd666613cb9da52fd..63f12b6c42adefca9fe9a5d7e5b34360ae79e018 100644 (file)
@@ -1,6 +1,7 @@
 BasedOnStyle: LLVM
-IndentWidth: 8
+IndentWidth: 4
 UseTab: Always
+TabWidth: 4
 BreakBeforeBraces: Custom
 Standard: Cpp11
 BraceWrapping:
@@ -16,7 +17,7 @@ BraceWrapping:
 FixNamespaceComments: false
 AllowShortIfStatementsOnASingleLine: false
 IndentCaseLabels: false
-AccessModifierOffset: -8
+AccessModifierOffset: -4
 ColumnLimit: 90
 AllowShortFunctionsOnASingleLine: InlineOnly
 SortIncludes: false
@@ -26,7 +27,7 @@ IncludeCategories:
   - Regex:           '^<.*'
     Priority:        1
 AlignAfterOpenBracket: DontAlign
-ContinuationIndentWidth: 16
-ConstructorInitializerIndentWidth: 16
+ContinuationIndentWidth: 8
+ConstructorInitializerIndentWidth: 8
 BreakConstructorInitializers: AfterColon
 AlwaysBreakTemplateDeclarations: Yes
index 660b5c8df3b207aeeeafd14c349515c96c2c268e..20411a332c09a5bc93535702427547800871081d 100644 (file)
@@ -21,24 +21,22 @@ on:
 
 jobs:
   build:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
-    - uses: actions/checkout@v2
-    - name: Set up JDK 1.8
-      uses: actions/setup-java@v1
-      with:
-        java-version: 1.8
+    - uses: actions/checkout@v3
     - name: Install deps
-      run: sudo apt-get update; sudo apt-get install -y --no-install-recommends gettext
+      run: |
+        sudo apt-get update
+        sudo apt-get install -y --no-install-recommends gettext openjdk-11-jdk-headless
     - name: Build with Gradle
       run: cd android; ./gradlew assemblerelease
     - name: Save armeabi artifact
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v3
       with:
         name: Minetest-armeabi-v7a.apk
         path: android/app/build/outputs/apk/release/app-armeabi-v7a-release-unsigned.apk
     - name: Save arm64 artifact
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v3
       with:
         name: Minetest-arm64-v8a.apk
         path: android/app/build/outputs/apk/release/app-arm64-v8a-release-unsigned.apk
index 417b4f65024aba44304466623199fd0a93bc9da2..2cc83923b3a00f4fb0aa351282af086dee5d39d3 100644 (file)
@@ -30,53 +30,53 @@ on:
       - '.dockerignore'
 
 jobs:
-  # This is our minor gcc compiler
-  gcc_6:
+  # Older gcc version (should be close to our minimum supported version)
+  gcc_5:
     runs-on: ubuntu-18.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install deps
         run: |
           source ./util/ci/common.sh
-          install_linux_deps g++-6
+          install_linux_deps g++-5
 
       - name: Build
         run: |
           ./util/ci/build.sh
         env:
-          CC: gcc-6
-          CXX: g++-6
+          CC: gcc-5
+          CXX: g++-5
 
       - name: Test
         run: |
           ./bin/minetest --run-unittests
 
-  # This is the current gcc compiler (available in bionic)
-  gcc_8:
-    runs-on: ubuntu-18.04
+  # Current gcc version
+  gcc_10:
+    runs-on: ubuntu-20.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install deps
         run: |
           source ./util/ci/common.sh
-          install_linux_deps g++-8
+          install_linux_deps g++-10
 
       - name: Build
         run: |
           ./util/ci/build.sh
         env:
-          CC: gcc-8
-          CXX: g++-8
+          CC: gcc-10
+          CXX: g++-10
 
       - name: Test
         run: |
           ./bin/minetest --run-unittests
 
-  # This is our minor clang compiler
+  # Older clang version (should be close to our minimum supported version)
   clang_3_9:
     runs-on: ubuntu-18.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install deps
         run: |
           source ./util/ci/common.sh
@@ -93,26 +93,26 @@ jobs:
         run: |
           ./bin/minetest --run-unittests
 
-      - name: Integration test
+      - name: Integration test + devtest
         run: |
           ./util/test_multiplayer.sh
 
-  # This is the current clang version
-  clang_9:
-    runs-on: ubuntu-18.04
+  # Current clang version
+  clang_10:
+    runs-on: ubuntu-20.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install deps
         run: |
           source ./util/ci/common.sh
-          install_linux_deps clang-9 valgrind libluajit-5.1-dev
+          install_linux_deps clang-10 valgrind libluajit-5.1-dev
 
       - name: Build
         run: |
           ./util/ci/build.sh
         env:
-          CC: clang-9
-          CXX: clang++-9
+          CC: clang-10
+          CXX: clang++-10
           CMAKE_FLAGS: "-DREQUIRE_LUAJIT=1"
 
       - name: Test
@@ -126,9 +126,9 @@ jobs:
   # Build with prometheus-cpp (server-only)
   clang_9_prometheus:
     name: "clang_9 (PROMETHEUS=1)"
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install deps
         run: |
           source ./util/ci/common.sh
@@ -150,34 +150,11 @@ jobs:
         run: |
           ./bin/minetestserver --run-unittests
 
-  # Build without freetype (client-only)
-  clang_9_no_freetype:
-    name: "clang_9 (FREETYPE=0)"
-    runs-on: ubuntu-18.04
-    steps:
-      - uses: actions/checkout@v2
-      - name: Install deps
-        run: |
-          source ./util/ci/common.sh
-          install_linux_deps clang-9
-
-      - name: Build
-        run: |
-          ./util/ci/build.sh
-        env:
-          CC: clang-9
-          CXX: clang++-9
-          CMAKE_FLAGS: "-DENABLE_FREETYPE=0 -DBUILD_SERVER=0"
-
-      - name: Test
-        run: |
-          ./bin/minetest --run-unittests
-
   docker:
     name: "Docker image"
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Build docker image
         run: |
           docker build . -t minetest:latest
@@ -185,13 +162,13 @@ jobs:
 
   win32:
     name: "MinGW cross-compiler (32-bit)"
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install compiler
         run: |
-          sudo apt-get update -q && sudo apt-get install gettext -qyy
-          wget http://minetest.kitsunemimi.pw/mingw-w64-i686_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
+          sudo apt-get update && sudo apt-get install -y gettext
+          wget http://minetest.kitsunemimi.pw/mingw-w64-i686_11.2.0_ubuntu20.04.tar.xz -O mingw.tar.xz
           sudo tar -xaf mingw.tar.xz -C /usr
 
       - name: Build
@@ -203,13 +180,13 @@ jobs:
 
   win64:
     name: "MinGW cross-compiler (64-bit)"
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install compiler
         run: |
-          sudo apt-get update -q && sudo apt-get install gettext -qyy
-          wget http://minetest.kitsunemimi.pw/mingw-w64-x86_64_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
+          sudo apt-get update && sudo apt-get install -y gettext
+          wget http://minetest.kitsunemimi.pw/mingw-w64-x86_64_11.2.0_ubuntu20.04.tar.xz -O mingw.tar.xz
           sudo tar -xaf mingw.tar.xz -C /usr
 
       - name: Build
@@ -222,13 +199,10 @@ jobs:
   msvc:
     name: VS 2019 ${{ matrix.config.arch }}-${{ matrix.type }}
     runs-on: windows-2019
-    #### Disabled due to Irrlicht switch
-    if: false
-    #### Disabled due to Irrlicht switch
     env:
-      VCPKG_VERSION: 0bf3923f9fab4001c00f0f429682a0853b5749e0
-#                    2020.11
-      vcpkg_packages: irrlicht zlib zstd curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit
+      VCPKG_VERSION: 5cf60186a241e84e8232641ee973395d4fde90e1
+      # 2022.02
+      vcpkg_packages: zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp opengl-registry
     strategy:
       fail-fast: false
       matrix:
@@ -249,11 +223,17 @@ jobs:
 # Enable it, when working on the installer.
 
     steps:
-      - name: Checkout
-        uses: actions/checkout@v2
+      - uses: actions/checkout@v3
+
+      - name: Checkout IrrlichtMt
+        uses: actions/checkout@v3
+        with:
+          repository: minetest/irrlicht
+          path: lib/irrlichtmt/
+          ref: "1.9.0mt5"
 
       - name: Restore from cache and run vcpkg
-        uses: lukka/run-vcpkg@v5
+        uses: lukka/run-vcpkg@v7
         with:
           vcpkgArguments: ${{env.vcpkg_packages}}
           vcpkgDirectory: '${{ github.workspace }}\vcpkg'
@@ -261,7 +241,7 @@ jobs:
           vcpkgGitCommitId: ${{ env.VCPKG_VERSION }}
           vcpkgTriplet: ${{ matrix.config.vcpkg_triplet }}
 
-      - name: CMake
+      - name: Minetest CMake
         run: |
           cmake ${{matrix.config.generator}}  `
           -DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}\vcpkg\scripts\buildsystems\vcpkg.cmake"  `
@@ -269,7 +249,7 @@ jobs:
           -DENABLE_POSTGRESQL=OFF  `
           -DRUN_IN_PLACE=${{ contains(matrix.type, 'portable') }} .
 
-      - name: Build
+      - name: Build Minetest
         run: cmake --build . --config Release
 
       - name: CPack
@@ -288,7 +268,7 @@ jobs:
       - name: Package Clean
         run: rm -r $env:GITHUB_WORKSPACE\Package\_CPack_Packages
 
-      - uses: actions/upload-artifact@v1
+      - uses: actions/upload-artifact@v3
         with:
           name: msvc-${{ matrix.config.arch }}-${{ matrix.type }}
           path: .\Package\
index 2bd884c7a6d4017defbdce808ec681671093cf5d..581ee06d6c19f657bc736c049ca02d8bd949489b 100644 (file)
@@ -26,12 +26,13 @@ on:
 jobs:
 
 #  clang_format:
-#    runs-on: ubuntu-18.04
+#    runs-on: ubuntu-20.04
 #    steps:
-#      - uses: actions/checkout@v2
+#      - uses: actions/checkout@v3
 #      - name: Install clang-format
 #        run: |
-#          sudo apt-get install clang-format-9 -qyy
+#          sudo apt-get update
+#          sudo apt-get install -y clang-format-9
 #
 #      - name: Run clang-format
 #        run: |
@@ -41,14 +42,13 @@ jobs:
 #          CLANG_FORMAT: clang-format-9
 
   clang_tidy:
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
     - name: Install deps
       run: |
-        sudo apt-get install clang-tidy-9 -qyy
         source ./util/ci/common.sh
-        install_linux_deps
+        install_linux_deps clang-tidy-9
 
     - name: Run clang-tidy
       run: |
diff --git a/.github/workflows/lua.yml b/.github/workflows/lua.yml
new file mode 100644 (file)
index 0000000..3af4a6e
--- /dev/null
@@ -0,0 +1,61 @@
+name: lua_lint
+
+# Lint on lua changes on builtin or if workflow changed
+on:
+  push:
+    paths:
+      - 'builtin/**.lua'
+      - 'games/devtest/**.lua'
+      - '.github/workflows/**.yml'
+  pull_request:
+    paths:
+      - 'builtin/**.lua'
+      - 'games/devtest/**.lua'
+      - '.github/workflows/**.yml'
+
+jobs:
+  # Note that the integration tests are also run build.yml, but only when C++ code is changed.
+  integration_tests:
+    name: "Compile and run multiplayer tests"
+    runs-on: ubuntu-20.04
+    steps:
+      - uses: actions/checkout@v3
+      - name: Install deps
+        run: |
+          source ./util/ci/common.sh
+          install_linux_deps clang-10 gdb libluajit-5.1-dev
+
+      - name: Build
+        run: |
+          ./util/ci/build.sh
+        env:
+          CC: clang-10
+          CXX: clang++-10
+          CMAKE_FLAGS: "-DENABLE_GETTEXT=0 -DBUILD_SERVER=0"
+
+      - name: Integration test + devtest
+        run: |
+          ./util/test_multiplayer.sh
+
+  luacheck:
+    name: "Builtin Luacheck and Unit Tests"
+    runs-on: ubuntu-20.04
+    steps:
+    - uses: actions/checkout@v3
+    - name: Install luarocks
+      run: |
+        sudo apt-get update && sudo apt-get install -y luarocks
+
+    - name: Install luarocks tools
+      run: |
+        luarocks install --local luacheck
+        luarocks install --local busted
+
+    - name: Run checks (builtin)
+      run: |
+        $HOME/.luarocks/bin/luacheck builtin
+        $HOME/.luarocks/bin/busted builtin
+
+    - name: Run checks (devtest)
+      run: |
+        $HOME/.luarocks/bin/luacheck --config=games/devtest/.luacheckrc games/devtest
diff --git a/.github/workflows/lua_lint.yml b/.github/workflows/lua_lint.yml
deleted file mode 100644 (file)
index 738e5af..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-name: lua_lint
-
-# Lint on lua changes on builtin or if workflow changed
-on:
-  push:
-    paths:
-      - 'builtin/**.lua'
-      - '.github/workflows/**.yml'
-  pull_request:
-    paths:
-      - 'builtin/**.lua'
-      - '.github/workflows/**.yml'
-
-jobs:
-  luacheck:
-    name: "Builtin Luacheck and Unit Tests"
-    runs-on: ubuntu-18.04
-    steps:
-    - uses: actions/checkout@v2
-    - name: Install luarocks
-      run: |
-        sudo apt-get install luarocks -qyy
-
-    - name: Install luarocks tools
-      run: |
-        luarocks install --local luacheck
-        luarocks install --local busted
-
-    - name: Run checks
-      run: |
-        $HOME/.luarocks/bin/luacheck builtin
-        $HOME/.luarocks/bin/busted builtin
index d97cff1aaccd4d690eb47f5624c17463a6832d16..c0278a38c0400241cee68187918dfc7e02c5b6e1 100644 (file)
@@ -22,7 +22,7 @@ on:
       - '.github/workflows/macos.yml'
 
 env:
-  IRRLICHT_TAG: 1.9.0mt3
+  IRRLICHT_TAG: 1.9.0mt5
   MINETEST_GAME_REPO: https://github.com/minetest/minetest_game.git
   MINETEST_GAME_BRANCH: master
   MINETEST_GAME_NAME: minetest_game
@@ -31,7 +31,7 @@ jobs:
   build:
     runs-on: macos-10.15
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Install deps
         run: |
           pkgs=(cmake freetype gettext gmp hiredis jpeg jsoncpp leveldb libogg libpng libvorbis luajit zstd)
@@ -45,8 +45,8 @@ jobs:
           git clone -b $MINETEST_GAME_BRANCH $MINETEST_GAME_REPO games/$MINETEST_GAME_NAME
           rm -rvf games/$MINETEST_GAME_NAME/.git
           git clone https://github.com/minetest/irrlicht -b $IRRLICHT_TAG lib/irrlichtmt
-          mkdir cmakebuild
-          cd cmakebuild
+          mkdir build
+          cd build
           cmake .. \
             -DCMAKE_OSX_DEPLOYMENT_TARGET=10.14 \
             -DCMAKE_FIND_FRAMEWORK=LAST \
@@ -60,7 +60,7 @@ jobs:
         run: |
           ./build/macos/minetest.app/Contents/MacOS/minetest --run-unittests
 
-      - uses: actions/upload-artifact@v2
+      - uses: actions/upload-artifact@v3
         with:
           name: minetest-macos
           path: ./build/macos/
index 2e410b48a65b6096781916f0bef8db9bb3b73033..8a963d3c9b09fe7278db06ffe695bde676a60b86 100644 (file)
@@ -107,6 +107,13 @@ CMakeDoxy*
 compile_commands.json
 *.apk
 *.zip
+# Visual Studio
+*.vcxproj*
+*.sln
+.vs/
 
 # Optional user provided library folder
 lib/irrlichtmt
+
+# Generated mod storage database
+client/mod_storage.sqlite
index 5b085c36c853e9d7d702f7c4bf24bea3d2baf648..c225bfcd47eaa9c95e2d24e299bd891a52bfb4f7 100644 (file)
@@ -9,7 +9,7 @@ stages:
   - deploy
 
 variables:
-  IRRLICHT_TAG: "1.9.0mt3"
+  IRRLICHT_TAG: "1.9.0mt5"
   MINETEST_GAME_REPO: "https://github.com/minetest/minetest_game.git"
   CONTAINER_IMAGE: registry.gitlab.com/$CI_PROJECT_PATH
 
@@ -20,11 +20,9 @@ variables:
    - DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential git cmake libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libleveldb-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev
   script:
     - git clone https://github.com/minetest/irrlicht -b $IRRLICHT_TAG lib/irrlichtmt
-    - mkdir cmakebuild
-    - cd cmakebuild
-    - cmake -DCMAKE_INSTALL_PREFIX=../artifact/minetest/usr/ -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE -DBUILD_SERVER=TRUE ..
-    - make -j2
-    - make install
+    - cmake -B build -DCMAKE_INSTALL_PREFIX=../artifact/minetest/usr/ -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE -DBUILD_SERVER=TRUE ..
+    - cmake --build build --parallel $(($(nproc) + 1))
+    - cmake --install build
   artifacts:
     when: on_success
     expire_in: 1h
@@ -198,25 +196,12 @@ build:fedora-28:
   before_script:
     - apt-get update
     - DEBIAN_FRONTEND=noninteractive apt-get install -y wget xz-utils unzip git cmake gettext
-    - wget -nv http://minetest.kitsunemimi.pw/mingw-w64-${WIN_ARCH}_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
+    - wget -nv http://minetest.kitsunemimi.pw/mingw-w64-${WIN_ARCH}_11.2.0_ubuntu20.04.tar.xz -O mingw.tar.xz
     - tar -xaf mingw.tar.xz -C /usr
 
 .build_win_template:
   extends: .generic_win_template
   stage: build
-  artifacts:
-    expire_in: 1h
-    paths:
-      - build/build/*.zip
-
-.package_win_template:
-  extends: .generic_win_template
-  stage: package
-  script:
-    - unzip build/build/*.zip
-    - cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libgcc*.dll minetest-*-win*/bin/
-    - cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libstdc++*.dll minetest-*-win*/bin/
-    - cp -p /usr/${WIN_ARCH}-w64-mingw32/bin/libwinpthread*.dll minetest-*-win*/bin/
   artifacts:
     expire_in: 90 day
     paths:
@@ -226,28 +211,15 @@ build:win32:
   extends: .build_win_template
   script:
     - EXISTING_MINETEST_DIR=$PWD ./util/buildbot/buildwin32.sh build
+    - unzip -q build/build/*.zip
   variables:
     WIN_ARCH: "i686"
 
-package:win32:
-  extends: .package_win_template
-  needs:
-    - build:win32
-  variables:
-    WIN_ARCH: "i686"
-
-
 build:win64:
   extends: .build_win_template
   script:
     - EXISTING_MINETEST_DIR=$PWD ./util/buildbot/buildwin64.sh build
-  variables:
-    WIN_ARCH: "x86_64"
-
-package:win64:
-  extends: .package_win_template
-  needs:
-    - build:win64
+    - unzip -q build/build/*.zip
   variables:
     WIN_ARCH: "x86_64"
 
index deb327c5bc17df45e6c2f4b7d1ce58a80a4e34b9..018e233da2b19b23b5ab740a1bae4e46bfa8f0aa 100644 (file)
@@ -11,13 +11,14 @@ endif()
 project(minetest)
 set(PROJECT_NAME_CAPITALIZED "Dragonfire")
 
-set(CMAKE_CXX_STANDARD 11)
-set(GCC_MINIMUM_VERSION "4.8")
-set(CLANG_MINIMUM_VERSION "3.4")
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
+set(GCC_MINIMUM_VERSION "5.1")
+set(CLANG_MINIMUM_VERSION "3.5")
 
 # Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing
 set(VERSION_MAJOR 5)
-set(VERSION_MINOR 5)
+set(VERSION_MINOR 6)
 set(VERSION_PATCH 0)
 set(VERSION_EXTRA "dragonfire" CACHE STRING "Stuff to append to version string")
 
@@ -26,7 +27,7 @@ set(DEVELOPMENT_BUILD FALSE)
 
 set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
 if(VERSION_EXTRA)
-       set(VERSION_STRING ${VERSION_STRING}-${VERSION_EXTRA})
+       set(VERSION_STRING "${VERSION_STRING}-${VERSION_EXTRA}")
 elseif(DEVELOPMENT_BUILD)
        set(VERSION_STRING "${VERSION_STRING}-dev")
 endif()
@@ -51,7 +52,7 @@ set(RUN_IN_PLACE ${DEFAULT_RUN_IN_PLACE} CACHE BOOL
 set(BUILD_CLIENT TRUE CACHE BOOL "Build client")
 set(BUILD_SERVER FALSE CACHE BOOL "Build server")
 set(BUILD_UNITTESTS TRUE CACHE BOOL "Build unittests")
-
+set(BUILD_BENCHMARKS FALSE CACHE BOOL "Build benchmarks")
 
 set(WARN_ALL TRUE CACHE BOOL "Enable -Wall for Release build")
 
@@ -64,8 +65,21 @@ endif()
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
 
 
+set(IRRLICHTMT_BUILD_DIR "" CACHE PATH "Path to IrrlichtMt build directory.")
+if(NOT "${IRRLICHTMT_BUILD_DIR}" STREQUAL "")
+       find_package(IrrlichtMt QUIET
+               PATHS "${IRRLICHTMT_BUILD_DIR}"
+               NO_DEFAULT_PATH
+       )
+
+       if(NOT TARGET IrrlichtMt::IrrlichtMt)
+               # find_package() searches certain subdirectories. ${PATH}/cmake is not
+               # the only one, but it is the one where IrrlichtMt is supposed to export
+               # IrrlichtMtConfig.cmake
+               message(FATAL_ERROR "Could not find IrrlichtMtConfig.cmake in ${IRRLICHTMT_BUILD_DIR}/cmake.")
+       endif()
 # This is done here so that relative search paths are more reasonable
-if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt")
+elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt")
        message(STATUS "Using user-provided IrrlichtMt at subdirectory 'lib/irrlichtmt'")
        if(BUILD_CLIENT)
                # tell IrrlichtMt to create a static library
@@ -101,11 +115,13 @@ else()
                # Note that we can't use target_include_directories() since that doesn't work for IMPORTED targets before CMake 3.11
                set_target_properties(IrrlichtMt::IrrlichtMt PROPERTIES
                        INTERFACE_INCLUDE_DIRECTORIES "${IRRLICHT_INCLUDE_DIR}")
-       else()
-               message(STATUS "Found IrrlichtMt ${IrrlichtMt_VERSION}")
        endif()
 endif()
 
+if(TARGET IrrlichtMt::IrrlichtMt)
+       message(STATUS "Found IrrlichtMt ${IrrlichtMt_VERSION}")
+endif()
+
 
 # Installation
 
@@ -135,15 +151,16 @@ elseif(UNIX) # Linux, BSD etc
                set(ICONDIR "unix/icons")
                set(LOCALEDIR "locale")
        else()
-               set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}")
-               set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
-               set(DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}")
-               set(MANDIR "${CMAKE_INSTALL_PREFIX}/share/man")
+               include(GNUInstallDirs)
+               set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}")
+               set(BINDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
+               set(DOCDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}")
+               set(MANDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_MANDIR}")
                set(EXAMPLE_CONF_DIR ${DOCDIR})
-               set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
-               set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/metainfo")
-               set(ICONDIR "${CMAKE_INSTALL_PREFIX}/share/icons")
-               set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale")
+               set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/applications")
+               set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/metainfo")
+               set(ICONDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/icons")
+               set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}")
        endif()
 endif()
 
@@ -246,10 +263,10 @@ endif()
 find_package(GMP REQUIRED)
 find_package(Json REQUIRED)
 find_package(Lua REQUIRED)
-
-# JsonCpp doesn't compile well on GCC 4.8
-if(NOT USE_SYSTEM_JSONCPP)
-       set(GCC_MINIMUM_VERSION "4.9")
+if(NOT USE_LUAJIT)
+       set(LUA_BIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/bitop)
+       set(LUA_BIT_LIBRARY bitop)
+       add_subdirectory(lib/bitop)
 endif()
 
 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -264,9 +281,12 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang")
        endif()
 endif()
 
+if(BUILD_BENCHMARKS)
+       add_subdirectory(lib/catch2)
+endif()
+
 # Subdirectories
 # Be sure to add all relevant definitions above this
-
 add_subdirectory(src)
 
 
index 8d1008fa2ed1a93507afc0e8e254ef4a7f7b98a2..3dd82e772cd3c16347d94c222bfab045ec692951 100644 (file)
@@ -27,23 +27,20 @@ RUN apk add --no-cache git build-base cmake sqlite-dev curl-dev zlib-dev zstd-de
 
 WORKDIR /usr/src/
 RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp/ && \
-       mkdir prometheus-cpp/build && \
-       cd prometheus-cpp/build && \
-       cmake .. \
+       cd prometheus-cpp && \
+       cmake -B build \
                -DCMAKE_INSTALL_PREFIX=/usr/local \
                -DCMAKE_BUILD_TYPE=Release \
                -DENABLE_TESTING=0 \
                -GNinja && \
-       ninja && \
-       ninja install
+       cmake --build build && \
+       cmake --install build
 
 RUN git clone --depth=1 https://github.com/minetest/irrlicht/ -b ${IRRLICHT_VERSION} && \
        cp -r irrlicht/include /usr/include/irrlichtmt
 
 WORKDIR /usr/src/minetest
-RUN mkdir build && \
-       cd build && \
-       cmake .. \
+RUN cmake -B build \
                -DCMAKE_INSTALL_PREFIX=/usr/local \
                -DCMAKE_BUILD_TYPE=Release \
                -DBUILD_SERVER=TRUE \
@@ -51,8 +48,8 @@ RUN mkdir build && \
                -DBUILD_UNITTESTS=FALSE \
                -DBUILD_CLIENT=FALSE \
                -GNinja && \
-       ninja && \
-       ninja install
+       cmake --build build && \
+       cmake --install build
 
 ARG DOCKER_IMAGE=alpine:3.14
 FROM $DOCKER_IMAGE AS runtime
index 5f4dded5900b65677079e66c06e73409a6323757..b28a0ff06c63ee8dbc93c7cd761bb9290509c9e2 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Minetest
 
 Minetest is a free open-source voxel game engine with easy modding and game creation.
 
-Copyright (C) 2010-2020 Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-2022 Perttu Ahola <celeron55@gmail.com>
 and contributors (see source file comments and the version control log)
 
 In case you downloaded the source code
@@ -132,10 +132,11 @@ Compiling
 
 | Dependency | Version | Commentary |
 |------------|---------|------------|
-| GCC        | 4.9+    | Can be replaced with Clang 3.4+ |
+| GCC        | 5.1+    | or Clang 3.5+ |
 | CMake      | 3.5+    |            |
 | IrrlichtMt | -       | Custom version of Irrlicht, see https://github.com/minetest/irrlicht |
-| SQLite3    | 3.0+    |            |
+| Freetype   | 2.0+    |            |
+| SQLite3    | 3+      |            |
 | Zstd       | 1.0+    |            |
 | LuaJIT     | 2.0+    | Bundled Lua 5.1 is used if not present |
 | GMP        | 5.0.0+  | Bundled mini-GMP is used if not present |
@@ -143,12 +144,12 @@ Compiling
 
 For Debian/Ubuntu users:
 
-    sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev
+    sudo apt install g++ make libc6-dev cmake libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libzstd-dev libluajit-5.1-dev
 
 For Fedora users:
 
     sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel spatialindex-devel libzstd-devel
-    
+
 For Arch users:
 
     sudo pacman -S base-devel libcurl-gnutls cmake libxxf86vm libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses zstd
@@ -224,10 +225,13 @@ Run it:
   - Debug build is slower, but gives much more useful output in a debugger.
 - If you build a bare server you don't need to have the Irrlicht or IrrlichtMt library installed.
   - In that case use `-DIRRLICHT_INCLUDE_DIR=/some/where/irrlicht/include`.
-- IrrlichtMt can also be installed somewhere that is not a standard install path.
-  - In that case use `-DCMAKE_PREFIX_PATH=/path/to/install_prefix`
-  - The path must be set so that `$(CMAKE_PREFIX_PATH)/lib/cmake/IrrlichtMt` exists
-    or that `$(CMAKE_PREFIX_PATH)` is the path of an IrrlichtMt build folder.
+
+- Minetest will use the IrrlichtMt package that is found first, given by the following order:
+  1. Specified `IRRLICHTMT_BUILD_DIR` CMake variable
+  2. `${PROJECT_SOURCE_DIR}/lib/irrlichtmt` (if existent)
+  3. Installation of IrrlichtMt in the system-specific library paths
+  4. For server builds with disabled `BUILD_CLIENT` variable, the headers from `IRRLICHT_INCLUDE_DIR` will be used.
+  - NOTE: Changing the IrrlichtMt build directory (includes system installs) requires regenerating the CMake cache (`rm CMakeCache.txt`)
 
 ### CMake options
 
@@ -236,6 +240,7 @@ General options and their default values:
     BUILD_CLIENT=TRUE          - Build Minetest client
     BUILD_SERVER=FALSE         - Build Minetest server
     BUILD_UNITTESTS=TRUE       - Build unittest sources
+    BUILD_BENCHMARKS=FALSE     - Build benchmark sources
     CMAKE_BUILD_TYPE=Release   - Type of build (Release vs. Debug)
         Release                - Release build
         Debug                  - Debug build
@@ -244,9 +249,8 @@ General options and their default values:
         MinSizeRel             - Release build with -Os passed to compiler to make executable as small as possible
     ENABLE_CURL=ON             - Build with cURL; Enables use of online mod repo, public serverlist and remote media fetching via http
     ENABLE_CURSES=ON           - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
-    ENABLE_FREETYPE=ON         - Build with FreeType2; Allows using TTF fonts
     ENABLE_GETTEXT=ON          - Build with Gettext; Allows using translations
-    ENABLE_GLES=OFF            - Build for OpenGL ES instead of OpenGL (requires support by IrrlichtMt)
+    ENABLE_GLES=OFF            - Enable extra support code for OpenGL ES (requires support by IrrlichtMt)
     ENABLE_LEVELDB=ON          - Build with LevelDB; Enables use of LevelDB map backend
     ENABLE_POSTGRESQL=ON       - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
     ENABLE_REDIS=ON            - Build with libhiredis; Enables use of Redis map backend
@@ -256,10 +260,10 @@ General options and their default values:
     ENABLE_PROMETHEUS=OFF      - Build with Prometheus metrics exporter (listens on tcp/30000 by default)
     ENABLE_SYSTEM_GMP=ON       - Use GMP from system (much faster than bundled mini-gmp)
     ENABLE_SYSTEM_JSONCPP=ON   - Use JsonCPP from system
-    OPENGL_GL_PREFERENCE=LEGACY - Linux client build only; See CMake Policy CMP0072 for reference
     RUN_IN_PLACE=FALSE         - Create a portable install (worlds, settings etc. in current directory)
     USE_GPROF=FALSE            - Enable profiling using GProf
     VERSION_EXTRA=             - Text to append to version (e.g. VERSION_EXTRA=foobar -> Minetest 0.4.9-foobar)
+    ENABLE_TOUCH=FALSE         - Enable Touchscreen support (requires support by IrrlichtMt)
 
 Library specific options:
 
@@ -268,10 +272,11 @@ Library specific options:
     CURL_LIBRARY                    - Only if building with cURL; path to libcurl.a/libcurl.so/libcurl.lib
     EGL_INCLUDE_DIR                 - Only if building with GLES; directory that contains egl.h
     EGL_LIBRARY                     - Only if building with GLES; path to libEGL.a/libEGL.so
-    FREETYPE_INCLUDE_DIR_freetype2  - Only if building with FreeType 2; directory that contains an freetype directory with files such as ftimage.h in it
-    FREETYPE_INCLUDE_DIR_ft2build   - Only if building with FreeType 2; directory that contains ft2build.h
-    FREETYPE_LIBRARY                - Only if building with FreeType 2; path to libfreetype.a/libfreetype.so/freetype.lib
-    FREETYPE_DLL                    - Only if building with FreeType 2 on Windows; path to libfreetype.dll
+    EXTRA_DLL                       - Only on Windows; optional paths to additional DLLs that should be packaged
+    FREETYPE_INCLUDE_DIR_freetype2  - Directory that contains files such as ftimage.h
+    FREETYPE_INCLUDE_DIR_ft2build   - Directory that contains ft2build.h
+    FREETYPE_LIBRARY                - Path to libfreetype.a/libfreetype.so/freetype.lib
+    FREETYPE_DLL                    - Only on Windows; path to libfreetype-6.dll
     GETTEXT_DLL                     - Only when building with gettext on Windows; paths to libintl + libiconv DLLs
     GETTEXT_INCLUDE_DIR             - Only when building with gettext; directory that contains iconv.h
     GETTEXT_LIBRARY                 - Only when building with gettext on Windows; path to libintl.dll.a
@@ -295,15 +300,12 @@ Library specific options:
     OPENAL_DLL                      - Only if building with sound on Windows; path to OpenAL32.dll
     OPENAL_INCLUDE_DIR              - Only if building with sound; directory where al.h is located
     OPENAL_LIBRARY                  - Only if building with sound; path to libopenal.a/libopenal.so/OpenAL32.lib
-    OPENGLES2_INCLUDE_DIR           - Only if building with GLES; directory that contains gl2.h
-    OPENGLES2_LIBRARY               - Only if building with GLES; path to libGLESv2.a/libGLESv2.so
     SQLITE3_INCLUDE_DIR             - Directory that contains sqlite3.h
     SQLITE3_LIBRARY                 - Path to libsqlite3.a/libsqlite3.so/sqlite3.lib
     VORBISFILE_LIBRARY              - Only if building with sound; path to libvorbisfile.a/libvorbisfile.so/libvorbisfile.dll.a
     VORBIS_DLL                      - Only if building with sound on Windows; paths to vorbis DLLs
     VORBIS_INCLUDE_DIR              - Only if building with sound; directory that contains a directory vorbis with vorbisenc.h inside
     VORBIS_LIBRARY                  - Only if building with sound; path to libvorbis.a/libvorbis.so/libvorbis.dll.a
-    XXF86VM_LIBRARY                 - Only on Linux; path to libXXf86vm.a/libXXf86vm.so
     ZLIB_DLL                        - Only on Windows; path to zlib1.dll
     ZLIB_INCLUDE_DIR                - Directory that contains zlib.h
     ZLIB_LIBRARY                    - Path to libz.a/libz.so/zlib.lib
@@ -326,13 +328,12 @@ It is highly recommended to use vcpkg as package manager.
 
 After you successfully built vcpkg you can easily install the required libraries:
 ```powershell
-vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit gmp jsoncpp --triplet x64-windows
+vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp opengl-registry --triplet x64-windows
 ```
 
 - **Don't forget about IrrlichtMt.** The easiest way is to clone it to `lib/irrlichtmt` as described in the Linux section.
 - `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
 - `openal-soft`, `libvorbis` and `libogg` are optional, but required to use sound.
-- `freetype` is optional, it allows true-type font rendering.
 - `luajit` is optional, it replaces the integrated Lua interpreter with a faster just-in-time interpreter.
 - `gmp` and `jsoncpp` are optional, otherwise the bundled versions will be compiled
 
@@ -381,6 +382,60 @@ Build the binaries as described above, but make sure you unselect `RUN_IN_PLACE`
 Open the generated project file with Visual Studio. Right-click **Package** and choose **Generate**.
 It may take some minutes to generate the installer.
 
+### Compiling on MacOS
+
+#### Requirements
+- [Homebrew](https://brew.sh/)
+- [Git](https://git-scm.com/downloads)
+
+Install dependencies with homebrew:
+
+```
+brew install cmake freetype gettext gmp hiredis jpeg jsoncpp leveldb libogg libpng libvorbis luajit zstd
+```
+
+#### Download
+
+Download source (this is the URL to the latest of source repository, which might not work at all times) using Git:
+
+```bash
+git clone --depth 1 https://github.com/minetest/minetest.git
+cd minetest
+```
+
+Download minetest_game (otherwise only the "Development Test" game is available) using Git:
+
+```
+git clone --depth 1 https://github.com/minetest/minetest_game.git games/minetest_game
+```
+
+Download Minetest's fork of Irrlicht:
+
+```
+git clone --depth 1 https://github.com/minetest/irrlicht.git lib/irrlichtmt
+```
+
+#### Build
+
+```bash
+mkdir build
+cd build
+
+cmake .. \
+    -DCMAKE_OSX_DEPLOYMENT_TARGET=10.14 \
+    -DCMAKE_FIND_FRAMEWORK=LAST \
+    -DCMAKE_INSTALL_PREFIX=../build/macos/ \
+    -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE
+
+make -j$(sysctl -n hw.logicalcpu)
+make install
+```
+
+#### Run
+
+```
+open ./build/macos/minetest.app
+```
 
 Docker
 ------
index 53fe8591014425f7b525b79e9485810675677802..e8ba9572204fe7e04da0eac0993694ef0459cab7 100644 (file)
@@ -1,12 +1,12 @@
 apply plugin: 'com.android.application'
 android {
-       compileSdkVersion 29
+       compileSdkVersion 30
        buildToolsVersion '30.0.3'
-       ndkVersion '22.0.7026061'
+       ndkVersion "$ndk_version"
        defaultConfig {
                applicationId 'net.minetest.minetest'
                minSdkVersion 16
-               targetSdkVersion 29
+               targetSdkVersion 30
                versionName "${versionMajor}.${versionMinor}.${versionPatch}"
                versionCode project.versionCode
        }
@@ -68,7 +68,7 @@ task prepareAssets() {
                from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders"
        }
        copy {
-               from "../native/deps/Android/Irrlicht/shaders" into "${assetsFolder}/client/shaders/Irrlicht"
+               from "../native/deps/armeabi-v7a/Irrlicht/Shaders" into "${assetsFolder}/client/shaders/Irrlicht"
        }
        copy {
                from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts"
@@ -112,5 +112,5 @@ android.applicationVariants.all { variant ->
 
 dependencies {
        implementation project(':native')
-       implementation 'androidx.appcompat:appcompat:1.2.0'
+       implementation 'androidx.appcompat:appcompat:1.3.1'
 }
index fa93e70696fa8bbf8c497809fc7ec942198eaa34..6ea677cb99ab859a0dd62e0e6f04f96067885aa7 100644 (file)
@@ -30,7 +30,8 @@
                        android:configChanges="orientation|keyboardHidden|navigation|screenSize"
                        android:maxAspectRatio="3.0"
                        android:screenOrientation="sensorLandscape"
-                       android:theme="@style/AppTheme">
+                       android:theme="@style/AppTheme"
+                       android:exported="true">
                        <intent-filter>
                                <action android:name="android.intent.action.MAIN" />
                                <category android:name="android.intent.category.LAUNCHER" />
@@ -44,7 +45,8 @@
                        android:launchMode="singleTask"
                        android:maxAspectRatio="3.0"
                        android:screenOrientation="sensorLandscape"
-                       android:theme="@style/AppTheme">
+                       android:theme="@style/AppTheme"
+                       android:exported="true">
                        <intent-filter>
                                <action android:name="android.intent.action.MAIN" />
                        </intent-filter>
diff --git a/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java b/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java
deleted file mode 100644 (file)
index 6d4b6ab..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Minetest
-Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
-Copyright (C) 2014-2020 ubulem,  Bektur Mambetov <berkut87@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-package net.minetest.minetest;
-
-import android.content.Intent;
-import android.os.AsyncTask;
-import android.widget.Toast;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.ref.WeakReference;
-
-public class CopyZipTask extends AsyncTask<String, Void, String> {
-
-       private final WeakReference<AppCompatActivity> activityRef;
-
-       CopyZipTask(AppCompatActivity activity) {
-               activityRef = new WeakReference<>(activity);
-       }
-
-       protected String doInBackground(String... params) {
-               copyAsset(params[0]);
-               return params[0];
-       }
-
-       @Override
-       protected void onPostExecute(String result) {
-               startUnzipService(result);
-       }
-
-       private void copyAsset(String zipName) {
-               String filename = zipName.substring(zipName.lastIndexOf("/") + 1);
-               try (InputStream in = activityRef.get().getAssets().open(filename);
-                    OutputStream out = new FileOutputStream(zipName)) {
-                       copyFile(in, out);
-               } catch (IOException e) {
-                       AppCompatActivity activity = activityRef.get();
-                       if (activity != null) {
-                               activity.runOnUiThread(() -> Toast.makeText(activityRef.get(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show());
-                       }
-                       cancel(true);
-               }
-       }
-
-       private void copyFile(InputStream in, OutputStream out) throws IOException {
-               byte[] buffer = new byte[1024];
-               int read;
-               while ((read = in.read(buffer)) != -1)
-                       out.write(buffer, 0, read);
-       }
-
-       private void startUnzipService(String file) {
-               Intent intent = new Intent(activityRef.get(), UnzipService.class);
-               intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file);
-               AppCompatActivity activity = activityRef.get();
-               if (activity != null) {
-                       activity.startService(intent);
-               }
-       }
-}
index bdf7641383cd1f2a4086bce20b8747120bc37bb9..46fc9b1de27a55feaba9ca0676dfb02d575d110b 100644 (file)
@@ -171,4 +171,12 @@ public class GameActivity extends NativeActivity {
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
                startActivity(browserIntent);
        }
+
+       public String getUserDataPath() {
+               return Utils.getUserDataDirectory(this).getAbsolutePath();
+       }
+
+       public String getCachePath() {
+               return Utils.getCacheDirectory(this).getAbsolutePath();
+       }
 }
index 2aa50d9ad5d2926dd13ea6969dc06b20dcd82c8c..b6567b4b75845de0f74d900219903fededff44c8 100644 (file)
@@ -29,12 +29,14 @@ import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Environment;
 import android.view.View;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.core.app.ActivityCompat;
 import androidx.core.content.ContextCompat;
@@ -43,11 +45,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import static net.minetest.minetest.UnzipService.ACTION_FAILURE;
-import static net.minetest.minetest.UnzipService.ACTION_PROGRESS;
-import static net.minetest.minetest.UnzipService.ACTION_UPDATE;
-import static net.minetest.minetest.UnzipService.FAILURE;
-import static net.minetest.minetest.UnzipService.SUCCESS;
+import static net.minetest.minetest.UnzipService.*;
 
 public class MainActivity extends AppCompatActivity {
        private final static int versionCode = BuildConfig.VERSION_CODE;
@@ -56,26 +54,40 @@ public class MainActivity extends AppCompatActivity {
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
        private static final String SETTINGS = "MinetestSettings";
        private static final String TAG_VERSION_CODE = "versionCode";
+
        private ProgressBar mProgressBar;
        private TextView mTextView;
        private SharedPreferences sharedPreferences;
+
        private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                        int progress = 0;
-                       if (intent != null)
+                       @StringRes int message = 0;
+                       if (intent != null) {
                                progress = intent.getIntExtra(ACTION_PROGRESS, 0);
-                       if (progress >= 0) {
+                               message = intent.getIntExtra(ACTION_PROGRESS_MESSAGE, 0);
+                       }
+
+                       if (progress == FAILURE) {
+                               Toast.makeText(MainActivity.this, intent.getStringExtra(ACTION_FAILURE), Toast.LENGTH_LONG).show();
+                               finish();
+                       } else if (progress == SUCCESS) {
+                               startNative();
+                       } else {
                                if (mProgressBar != null) {
                                        mProgressBar.setVisibility(View.VISIBLE);
-                                       mProgressBar.setProgress(progress);
+                                       if (progress == INDETERMINATE) {
+                                               mProgressBar.setIndeterminate(true);
+                                       } else {
+                                               mProgressBar.setIndeterminate(false);
+                                               mProgressBar.setProgress(progress);
+                                       }
                                }
                                mTextView.setVisibility(View.VISIBLE);
-                       } else if (progress == FAILURE) {
-                               Toast.makeText(MainActivity.this, intent.getStringExtra(ACTION_FAILURE), Toast.LENGTH_LONG).show();
-                               finish();
-                       } else if (progress == SUCCESS)
-                               startNative();
+                               if (message != 0)
+                                       mTextView.setText(message);
+                       }
                }
        };
 
@@ -88,7 +100,9 @@ public class MainActivity extends AppCompatActivity {
                mProgressBar = findViewById(R.id.progressBar);
                mTextView = findViewById(R.id.textView);
                sharedPreferences = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE);
-               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+
+               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
+                               Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
                        checkPermission();
                else
                        checkAppVersion();
@@ -120,6 +134,7 @@ public class MainActivity extends AppCompatActivity {
                                if (grantResult != PackageManager.PERMISSION_GRANTED) {
                                        Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show();
                                        finish();
+                                       return;
                                }
                        }
                        checkAppVersion();
@@ -127,10 +142,27 @@ public class MainActivity extends AppCompatActivity {
        }
 
        private void checkAppVersion() {
-               if (sharedPreferences.getInt(TAG_VERSION_CODE, 0) == versionCode)
+               if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                       Toast.makeText(this, R.string.no_external_storage, Toast.LENGTH_LONG).show();
+                       finish();
+                       return;
+               }
+
+               if (UnzipService.getIsRunning()) {
+                       mProgressBar.setVisibility(View.VISIBLE);
+                       mProgressBar.setIndeterminate(true);
+                       mTextView.setVisibility(View.VISIBLE);
+               } else if (sharedPreferences.getInt(TAG_VERSION_CODE, 0) == versionCode &&
+                               Utils.isInstallValid(this)) {
                        startNative();
-               else
-                       new CopyZipTask(this).execute(getCacheDir() + "/Minetest.zip");
+               } else {
+                       mProgressBar.setVisibility(View.VISIBLE);
+                       mProgressBar.setIndeterminate(true);
+                       mTextView.setVisibility(View.VISIBLE);
+
+                       Intent intent = new Intent(this, UnzipService.class);
+                       startService(intent);
+               }
        }
 
        private void startNative() {
index b69f7f36e6d34f512fd7fede537e0b2518474a49..a61a491398422488910d542ff586f63c50659862 100644 (file)
@@ -24,16 +24,22 @@ import android.app.IntentService;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
 import android.os.Environment;
-import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.StringRes;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -42,32 +48,61 @@ import java.util.zip.ZipInputStream;
 public class UnzipService extends IntentService {
        public static final String ACTION_UPDATE = "net.minetest.minetest.UPDATE";
        public static final String ACTION_PROGRESS = "net.minetest.minetest.PROGRESS";
+       public static final String ACTION_PROGRESS_MESSAGE = "net.minetest.minetest.PROGRESS_MESSAGE";
        public static final String ACTION_FAILURE = "net.minetest.minetest.FAILURE";
-       public static final String EXTRA_KEY_IN_FILE = "file";
        public static final int SUCCESS = -1;
        public static final int FAILURE = -2;
+       public static final int INDETERMINATE = -3;
        private final int id = 1;
        private NotificationManager mNotifyManager;
        private boolean isSuccess = true;
        private String failureMessage;
 
-       public UnzipService() {
-               super("net.minetest.minetest.UnzipService");
+       private static boolean isRunning = false;
+       public static synchronized boolean getIsRunning() {
+               return isRunning;
+       }
+       private static synchronized void setIsRunning(boolean v) {
+               isRunning = v;
        }
 
-       private void isDir(String dir, String location) {
-               File f = new File(location, dir);
-               if (!f.isDirectory())
-                       f.mkdirs();
+       public UnzipService() {
+               super("net.minetest.minetest.UnzipService");
        }
 
        @Override
        protected void onHandleIntent(Intent intent) {
-               createNotification();
-               unzip(intent);
+               Notification.Builder notificationBuilder = createNotification();
+               final File zipFile = new File(getCacheDir(), "Minetest.zip");
+               try {
+                       setIsRunning(true);
+                       File userDataDirectory = Utils.getUserDataDirectory(this);
+                       if (userDataDirectory == null) {
+                               throw new IOException("Unable to find user data directory");
+                       }
+
+                       try (InputStream in = this.getAssets().open(zipFile.getName())) {
+                               try (OutputStream out = new FileOutputStream(zipFile)) {
+                                       int readLen;
+                                       byte[] readBuffer = new byte[16384];
+                                       while ((readLen = in.read(readBuffer)) != -1) {
+                                               out.write(readBuffer, 0, readLen);
+                                       }
+                               }
+                       }
+
+                       migrate(notificationBuilder, userDataDirectory);
+                       unzip(notificationBuilder, zipFile, userDataDirectory);
+               } catch (IOException e) {
+                       isSuccess = false;
+                       failureMessage = e.getLocalizedMessage();
+               } finally {
+                       setIsRunning(false);
+                       zipFile.delete();
+               }
        }
 
-       private void createNotification() {
+       private Notification.Builder createNotification() {
                String name = "net.minetest.minetest";
                String channelId = "Minetest channel";
                String description = "notifications from Minetest";
@@ -92,66 +127,133 @@ public class UnzipService extends IntentService {
                } else {
                        builder = new Notification.Builder(this);
                }
+
+               Intent notificationIntent = new Intent(this, MainActivity.class);
+               notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+                       | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+               PendingIntent intent = PendingIntent.getActivity(this, 0,
+                       notificationIntent, 0);
+
                builder.setContentTitle(getString(R.string.notification_title))
                                .setSmallIcon(R.mipmap.ic_launcher)
-                               .setContentText(getString(R.string.notification_description));
+                               .setContentText(getString(R.string.notification_description))
+                               .setContentIntent(intent)
+                               .setOngoing(true)
+                               .setProgress(0, 0, true);
+
                mNotifyManager.notify(id, builder.build());
+               return builder;
        }
 
-       private void unzip(Intent intent) {
-               String zip = intent.getStringExtra(EXTRA_KEY_IN_FILE);
-               isDir("Minetest", Environment.getExternalStorageDirectory().toString());
-               String location = Environment.getExternalStorageDirectory() + File.separator + "Minetest" + File.separator;
+       private void unzip(Notification.Builder notificationBuilder, File zipFile, File userDataDirectory) throws IOException {
                int per = 0;
-               int size = getSummarySize(zip);
-               File zipFile = new File(zip);
+
+               int size;
+               try (ZipFile zipSize = new ZipFile(zipFile)) {
+                       size = zipSize.size();
+               }
+
                int readLen;
-               byte[] readBuffer = new byte[8192];
+               byte[] readBuffer = new byte[16384];
                try (FileInputStream fileInputStream = new FileInputStream(zipFile);
                     ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
                        ZipEntry ze;
                        while ((ze = zipInputStream.getNextEntry()) != null) {
                                if (ze.isDirectory()) {
                                        ++per;
-                                       isDir(ze.getName(), location);
-                               } else {
-                                       publishProgress(100 * ++per / size);
-                                       try (OutputStream outputStream = new FileOutputStream(location + ze.getName())) {
-                                               while ((readLen = zipInputStream.read(readBuffer)) != -1) {
-                                                       outputStream.write(readBuffer, 0, readLen);
-                                               }
+                                       Utils.createDirs(userDataDirectory, ze.getName());
+                                       continue;
+                               }
+                               publishProgress(notificationBuilder, R.string.loading, 100 * ++per / size);
+                               try (OutputStream outputStream = new FileOutputStream(
+                                               new File(userDataDirectory, ze.getName()))) {
+                                       while ((readLen = zipInputStream.read(readBuffer)) != -1) {
+                                               outputStream.write(readBuffer, 0, readLen);
                                        }
                                }
-                               zipFile.delete();
                        }
-               } catch (IOException e) {
-                       isSuccess = false;
-                       failureMessage = e.getLocalizedMessage();
                }
        }
 
-       private void publishProgress(int progress) {
+       void moveFileOrDir(@NonNull File src, @NonNull File dst) throws IOException {
+               try {
+                       Process p = new ProcessBuilder("/system/bin/mv",
+                               src.getAbsolutePath(), dst.getAbsolutePath()).start();
+                       int exitcode = p.waitFor();
+                       if (exitcode != 0)
+                               throw new IOException("Move failed with exit code " + exitcode);
+               } catch (InterruptedException e) {
+                       throw new IOException("Move operation interrupted");
+               }
+       }
+
+       boolean recursivelyDeleteDirectory(@NonNull File loc) {
+               try {
+                       Process p = new ProcessBuilder("/system/bin/rm", "-rf",
+                               loc.getAbsolutePath()).start();
+                       return p.waitFor() == 0;
+               } catch (IOException | InterruptedException e) {
+                       return false;
+               }
+       }
+
+       /**
+        * Migrates user data from deprecated external storage to app scoped storage
+        */
+       private void migrate(Notification.Builder notificationBuilder, File newLocation) throws IOException {
+               if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.R) {
+                       return;
+               }
+
+               File oldLocation = new File(Environment.getExternalStorageDirectory(), "Minetest");
+               if (!oldLocation.isDirectory())
+                       return;
+
+               publishProgress(notificationBuilder, R.string.migrating, 0);
+               newLocation.mkdir();
+
+               String[] dirs = new String[] { "worlds", "games", "mods", "textures", "client" };
+               for (int i = 0; i < dirs.length; i++) {
+                       publishProgress(notificationBuilder, R.string.migrating, 100 * i / dirs.length);
+                       File dir = new File(oldLocation, dirs[i]), dir2 = new File(newLocation, dirs[i]);
+                       if (dir.isDirectory() && !dir2.isDirectory()) {
+                               moveFileOrDir(dir, dir2);
+                       }
+               }
+
+               for (String filename : new String[] { "minetest.conf" }) {
+                       File file = new File(oldLocation, filename), file2 = new File(newLocation, filename);
+                       if (file.isFile() && !file2.isFile()) {
+                               moveFileOrDir(file, file2);
+                       }
+               }
+
+               recursivelyDeleteDirectory(oldLocation);
+       }
+
+       private void publishProgress(@Nullable  Notification.Builder notificationBuilder, @StringRes int message, int progress) {
                Intent intentUpdate = new Intent(ACTION_UPDATE);
                intentUpdate.putExtra(ACTION_PROGRESS, progress);
-               if (!isSuccess) intentUpdate.putExtra(ACTION_FAILURE, failureMessage);
+               intentUpdate.putExtra(ACTION_PROGRESS_MESSAGE, message);
+               if (!isSuccess)
+                       intentUpdate.putExtra(ACTION_FAILURE, failureMessage);
                sendBroadcast(intentUpdate);
-       }
 
-       private int getSummarySize(String zip) {
-               int size = 0;
-               try {
-                       ZipFile zipSize = new ZipFile(zip);
-                       size += zipSize.size();
-               } catch (IOException e) {
-                       Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+               if (notificationBuilder != null) {
+                       notificationBuilder.setContentText(getString(message));
+                       if (progress == INDETERMINATE) {
+                               notificationBuilder.setProgress(100, 50, true);
+                       } else {
+                               notificationBuilder.setProgress(100, progress, false);
+                       }
+                       mNotifyManager.notify(id, notificationBuilder.build());
                }
-               return size;
        }
 
        @Override
        public void onDestroy() {
                super.onDestroy();
                mNotifyManager.cancel(id);
-               publishProgress(isSuccess ? SUCCESS : FAILURE);
+               publishProgress(null, R.string.loading, isSuccess ? SUCCESS : FAILURE);
        }
 }
diff --git a/android/app/src/main/java/net/minetest/minetest/Utils.java b/android/app/src/main/java/net/minetest/minetest/Utils.java
new file mode 100644 (file)
index 0000000..b2553c8
--- /dev/null
@@ -0,0 +1,39 @@
+package net.minetest.minetest;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import java.io.File;
+
+public class Utils {
+       public static @NonNull File createDirs(File root, String dir) {
+               File f = new File(root, dir);
+               if (!f.isDirectory())
+                       f.mkdirs();
+
+               return f;
+       }
+
+       public static @Nullable File getUserDataDirectory(Context context) {
+               File extDir = context.getExternalFilesDir(null);
+               if (extDir == null) {
+                       return null;
+               }
+
+               return createDirs(extDir, "Minetest");
+       }
+
+       public static @Nullable File getCacheDirectory(Context context) {
+               return context.getCacheDir();
+       }
+
+       public static boolean isInstallValid(Context context) {
+               File userDataDirectory = getUserDataDirectory(context);
+               return userDataDirectory != null && userDataDirectory.isDirectory() &&
+                       new File(userDataDirectory, "games").isDirectory() &&
+                       new File(userDataDirectory, "builtin").isDirectory() &&
+                       new File(userDataDirectory, "client").isDirectory() &&
+                       new File(userDataDirectory, "textures").isDirectory();
+       }
+}
index e6f461f1415f279923f233163479f6a27bb0cdf5..93508c3cb9cf1edf2226704a28f4c1273218b0c5 100644 (file)
@@ -1,4 +1,5 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
@@ -14,7 +15,8 @@
                android:layout_marginRight="90dp"
                android:indeterminate="false"
                android:max="100"
-               android:visibility="gone" />
+               android:visibility="gone"
+               tools:visibility="visible" />
 
        <TextView
                android:id="@+id/textView"
@@ -25,6 +27,7 @@
                android:background="@android:color/transparent"
                android:text="@string/loading"
                android:textColor="#FEFEFE"
-               android:visibility="gone" />
+               android:visibility="gone"
+               tools:visibility="visible" />
 
 </RelativeLayout>
index 85238117f70ebf7b62e8d6d7ea7a6f7b894136db..99f948c99a2e6a8809b91187aa57d9c24da82c45 100644 (file)
@@ -3,9 +3,11 @@
 
        <string name="label">Minetest</string>
        <string name="loading">Loading&#8230;</string>
+       <string name="migrating">Migrating save data from old install&#8230; (this may take a while)</string>
        <string name="not_granted">Required permission wasn\'t granted, Minetest can\'t run without it</string>
        <string name="notification_title">Loading Minetest</string>
        <string name="notification_description">Less than 1 minute&#8230;</string>
        <string name="ime_dialog_done">Done</string>
+       <string name="no_external_storage">External storage isn\'t available. If you use an SDCard, please reinsert it. Otherwise, try restarting your phone or contacting the Minetest developers</string>
 
 </resources>
index 3ba51a4bb7558ba319990916b2ad6d96b87df94f..f861ba7027a72798bcaf2963cc12475b16c34ffb 100644 (file)
@@ -1,21 +1,22 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 
 project.ext.set("versionMajor", 5)      // Version Major
-project.ext.set("versionMinor", 5)      // Version Minor
+project.ext.set("versionMinor", 6)      // Version Minor
 project.ext.set("versionPatch", 0)      // Version Patch
 project.ext.set("versionExtra", "-dev") // Version Extra
-project.ext.set("versionCode", 32)      // Android Version Code
+project.ext.set("versionCode", 38)      // Android Version Code
 // NOTE: +2 after each release!
 // +1 for ARM and +1 for ARM64 APK's, because
 // each APK must have a larger `versionCode` than the previous
 
 buildscript {
+       ext.ndk_version = '23.0.7599858'
        repositories {
                google()
                jcenter()
        }
        dependencies {
-               classpath 'com.android.tools.build:gradle:4.1.1'
+               classpath 'com.android.tools.build:gradle:7.0.3'
                classpath 'de.undercouch:gradle-download-task:4.1.1'
                // NOTE: Do not place your application dependencies here; they belong
                // in the individual module build.gradle files
index 7fd9307d730679c6fab651833fa3b694d6353ffc..8ad73a75c039a1402b6ac795df1089118f38c4a7 100644 (file)
@@ -1,6 +1,5 @@
-#Fri Jan 08 17:52:00 UTC 2020
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
index 83f2acfdc319a24e8766cca78f32474ad7a22dd6..25e0c114864eb3e774bb17895759a17d4aba18c3 100755 (executable)
@@ -98,7 +98,7 @@ location of your Java installation."
     fi
 else
     JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+    command -v java >/dev/null || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
index 8ea6347b35a9c84df66c7a85a78e73c79acf3c3b..2ddc77135f7c6b01c33560a0735078adc1db6d34 100644 (file)
@@ -2,12 +2,12 @@ apply plugin: 'com.android.library'
 apply plugin: 'de.undercouch.download'
 
 android {
-       compileSdkVersion 29
+       compileSdkVersion 30
        buildToolsVersion '30.0.3'
-       ndkVersion '22.0.7026061'
+       ndkVersion "$ndk_version"
        defaultConfig {
                minSdkVersion 16
-               targetSdkVersion 29
+               targetSdkVersion 30
                externalNativeBuild {
                        ndkBuild {
                                arguments '-j' + Runtime.getRuntime().availableProcessors(),
@@ -41,58 +41,28 @@ android {
                                        arguments 'NDEBUG=1'
                                }
                        }
+
+                       ndk {
+                               debugSymbolLevel 'SYMBOL_TABLE'
+                       }
                }
        }
 }
 
 // get precompiled deps
-def folder = 'minetest_android_deps_binaries'
-
 task downloadDeps(type: Download) {
-       src 'https://github.com/minetest/' + folder + '/archive/master.zip'
+       src 'https://github.com/minetest/minetest_android_deps/releases/download/latest/deps.zip'
        dest new File(buildDir, 'deps.zip')
        overwrite false
 }
 
 task getDeps(dependsOn: downloadDeps, type: Copy) {
-       def deps = file('deps')
-       def f = file("$buildDir/" + folder + "-master")
-
-       if (!deps.exists() && !f.exists()) {
+       def deps = new File(buildDir.parent, 'deps')
+       if (!deps.exists()) {
+               deps.mkdir()
                from zipTree(downloadDeps.dest)
-               into buildDir
-       }
-
-       doLast {
-               if (!deps.exists()) {
-                       file(f).renameTo(file(deps))
-               }
-       }
-}
-
-// get sqlite
-def sqlite_ver = '3340000'
-task downloadSqlite(dependsOn: getDeps, type: Download) {
-       src 'https://www.sqlite.org/2020/sqlite-amalgamation-' + sqlite_ver + '.zip'
-       dest new File(buildDir, 'sqlite.zip')
-       overwrite false
-}
-
-task getSqlite(dependsOn: downloadSqlite, type: Copy) {
-       def sqlite = file('deps/Android/sqlite')
-       def f = file("$buildDir/sqlite-amalgamation-" + sqlite_ver)
-
-       if (!sqlite.exists() && !f.exists()) {
-               from zipTree(downloadSqlite.dest)
-               into buildDir
-       }
-
-       doLast {
-               if (!sqlite.exists()) {
-                       file(f).renameTo(file(sqlite))
-               }
+               into deps
        }
 }
 
 preBuild.dependsOn getDeps
-preBuild.dependsOn getSqlite
index 26e9b058b88014398ed9c7716e2055802b068d28..f8ca74d3c7a6eb37fa31a7ac1de22540b11d7f67 100644 (file)
@@ -4,62 +4,82 @@ LOCAL_PATH := $(call my-dir)/..
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := Curl
-LOCAL_SRC_FILES := deps/Android/Curl/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libcurl.a
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libcurl.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := Freetype
-LOCAL_SRC_FILES := deps/Android/Freetype/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libfreetype.a
+LOCAL_MODULE := libmbedcrypto
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libmbedcrypto.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := Irrlicht
-LOCAL_SRC_FILES := deps/Android/Irrlicht/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libIrrlichtMt.a
+LOCAL_MODULE := libmbedtls
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libmbedtls.a
 include $(PREBUILT_STATIC_LIBRARY)
 
-#include $(CLEAR_VARS)
-#LOCAL_MODULE := LevelDB
-#LOCAL_SRC_FILES := deps/Android/LevelDB/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libleveldb.a
-#include $(PREBUILT_STATIC_LIBRARY)
+include $(CLEAR_VARS)
+LOCAL_MODULE := libmbedx509
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Curl/libmbedx509.a
+include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := LuaJIT
-LOCAL_SRC_FILES := deps/Android/LuaJIT/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libluajit.a
+LOCAL_MODULE := Freetype
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Freetype/libfreetype.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := mbedTLS
-LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedtls.a
+LOCAL_MODULE := Iconv
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Iconv/libiconv.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := mbedx509
-LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedx509.a
+LOCAL_MODULE := libcharset
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Iconv/libcharset.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := mbedcrypto
-LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedcrypto.a
+LOCAL_MODULE := Irrlicht
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Irrlicht/libIrrlichtMt.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := LuaJIT
+LOCAL_SRC_FILES := deps/$(APP_ABI)/LuaJIT/libluajit.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := OpenAL
-LOCAL_SRC_FILES := deps/Android/OpenAL-Soft/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libopenal.a
+LOCAL_SRC_FILES := deps/$(APP_ABI)/OpenAL-Soft/libopenal.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := GetText
-LOCAL_SRC_FILES := deps/Android/GetText/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libintl.a
+LOCAL_MODULE := Gettext
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Gettext/libintl.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := SQLite3
+LOCAL_SRC_FILES := deps/$(APP_ABI)/SQLite/libsqlite3.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := Vorbis
-LOCAL_SRC_FILES := deps/Android/Vorbis/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libvorbis.a
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Vorbis/libvorbis.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libvorbisfile
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Vorbis/libvorbisfile.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libogg
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Vorbis/libogg.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := Zstd
-LOCAL_SRC_FILES := deps/Android/Zstd/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libzstd.a
+LOCAL_SRC_FILES := deps/$(APP_ABI)/Zstd/libzstd.a
 include $(PREBUILT_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -71,7 +91,6 @@ LOCAL_CFLAGS += \
        -DENABLE_GLES=1                 \
        -DUSE_CURL=1                    \
        -DUSE_SOUND=1                   \
-       -DUSE_FREETYPE=1                \
        -DUSE_LEVELDB=0                 \
        -DUSE_LUAJIT=1                  \
        -DUSE_GETTEXT=1                 \
@@ -96,18 +115,16 @@ LOCAL_C_INCLUDES := \
        ../../src/script                             \
        ../../lib/gmp                                \
        ../../lib/jsoncpp                            \
-       deps/Android/Curl/include                       \
-       deps/Android/Freetype/include                   \
-       deps/Android/Irrlicht/include                   \
-       deps/Android/LevelDB/include                    \
-       deps/Android/GetText/include                    \
-       deps/Android/libiconv/include                   \
-       deps/Android/libiconv/libcharset/include        \
-       deps/Android/LuaJIT/src                         \
-       deps/Android/OpenAL-Soft/include                \
-       deps/Android/sqlite                             \
-       deps/Android/Vorbis/include                     \
-       deps/Android/Zstd/include
+       deps/$(APP_ABI)/Curl/include                       \
+       deps/$(APP_ABI)/Freetype/include/freetype2         \
+       deps/$(APP_ABI)/Irrlicht/include                   \
+       deps/$(APP_ABI)/Gettext/include                    \
+       deps/$(APP_ABI)/Iconv/include                      \
+       deps/$(APP_ABI)/LuaJIT/include                     \
+       deps/$(APP_ABI)/OpenAL-Soft/include                \
+       deps/$(APP_ABI)/SQLite/include                     \
+       deps/$(APP_ABI)/Vorbis/include                     \
+       deps/$(APP_ABI)/Zstd/include
 
 LOCAL_SRC_FILES := \
        $(wildcard ../../src/client/*.cpp)           \
@@ -190,24 +207,24 @@ LOCAL_SRC_FILES := \
        ../../src/voxel.cpp                          \
        ../../src/voxelalgorithms.cpp
 
-# LevelDB backend is disabled
-#      ../../src/database/database-leveldb.cpp
-
 # GMP
 LOCAL_SRC_FILES += ../../lib/gmp/mini-gmp.c
 
 # JSONCPP
 LOCAL_SRC_FILES += ../../lib/jsoncpp/jsoncpp.cpp
 
-# iconv
-LOCAL_SRC_FILES += \
-       deps/Android/libiconv/lib/iconv.c               \
-       deps/Android/libiconv/libcharset/lib/localcharset.c
-
-# SQLite3
-LOCAL_SRC_FILES += deps/Android/sqlite/sqlite3.c
-
-LOCAL_STATIC_LIBRARIES += Curl Freetype Irrlicht OpenAL mbedTLS mbedx509 mbedcrypto Vorbis LuaJIT GetText Zstd android_native_app_glue $(PROFILER_LIBS) #LevelDB
+LOCAL_STATIC_LIBRARIES += \
+       Curl libmbedcrypto libmbedtls libmbedx509 \
+       Freetype \
+       Iconv libcharset \
+       Irrlicht \
+       LuaJIT \
+       OpenAL \
+       Gettext \
+       SQLite3 \
+       Vorbis libvorbisfile libogg \
+       Zstd
+LOCAL_STATIC_LIBRARIES += android_native_app_glue $(PROFILER_LIBS)
 
 LOCAL_LDLIBS := -lEGL -lGLESv1_CM -lGLESv2 -landroid -lOpenSLES
 
index 82f0148f0f7fa8fb9923527ee300d9679af2e188..9d959613759c2cf73038ce42ed51a1b765b6641f 100644 (file)
@@ -5,22 +5,22 @@ NDK_TOOLCHAIN_VERSION := clang
 APP_SHORT_COMMANDS := true
 APP_MODULES := Minetest
 
-APP_CPPFLAGS := -Ofast -fvisibility=hidden -fexceptions -Wno-deprecated-declarations -Wno-extra-tokens
+APP_CPPFLAGS := -O2 -fvisibility=hidden
 
 ifeq ($(APP_ABI),armeabi-v7a)
-APP_CPPFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb
+APP_CPPFLAGS += -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb
 endif
 
-#ifeq ($(APP_ABI),x86)
-#APP_CPPFLAGS += -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -funroll-loops
-#endif
+ifeq ($(APP_ABI),x86)
+APP_CPPFLAGS += -mssse3 -mfpmath=sse -funroll-loops
+endif
 
 ifndef NDEBUG
-APP_CPPFLAGS := -g -D_DEBUG -O0 -fno-omit-frame-pointer -fexceptions
+APP_CPPFLAGS := -g -Og -fno-omit-frame-pointer
 endif
 
-APP_CFLAGS   := $(APP_CPPFLAGS) -Wno-parentheses-equality #-Werror=shorten-64-to-32
-APP_CXXFLAGS := $(APP_CPPFLAGS) -frtti -std=gnu++17
+APP_CFLAGS   := $(APP_CPPFLAGS) -Wno-inconsistent-missing-override -Wno-parentheses-equality
+APP_CXXFLAGS := $(APP_CPPFLAGS) -fexceptions -frtti -std=gnu++14
 APP_LDFLAGS  := -Wl,--no-warn-mismatch,--gc-sections,--icf=safe
 
 ifeq ($(APP_ABI),arm64-v8a)
diff --git a/builtin/async/game.lua b/builtin/async/game.lua
new file mode 100644 (file)
index 0000000..e3119d8
--- /dev/null
@@ -0,0 +1,46 @@
+core.log("info", "Initializing asynchronous environment (game)")
+
+local function pack2(...)
+       return {n=select('#', ...), ...}
+end
+
+-- Entrypoint to run async jobs, called by C++
+function core.job_processor(func, params)
+       local retval = pack2(func(unpack(params, 1, params.n)))
+
+       return retval
+end
+
+-- Import a bunch of individual files from builtin/game/
+local gamepath = core.get_builtin_path() .. "game" .. DIR_DELIM
+local commonpath = core.get_builtin_path() .. "common" .. DIR_DELIM
+
+dofile(gamepath .. "constants.lua")
+dofile(gamepath .. "item_s.lua")
+dofile(gamepath .. "misc_s.lua")
+dofile(gamepath .. "features.lua")
+dofile(commonpath .. "voxelarea.lua")
+
+-- Transfer of globals
+do
+       local all = assert(core.transferred_globals)
+       core.transferred_globals = nil
+
+       -- reassemble other tables
+       all.registered_nodes = {}
+       all.registered_craftitems = {}
+       all.registered_tools = {}
+       for k, v in pairs(all.registered_items) do
+               if v.type == "node" then
+                       all.registered_nodes[k] = v
+               elseif v.type == "craftitem" then
+                       all.registered_craftitems[k] = v
+               elseif v.type == "tool" then
+                       all.registered_tools[k] = v
+               end
+       end
+
+       for k, v in pairs(all) do
+               core[k] = v
+       end
+end
diff --git a/builtin/async/init.lua b/builtin/async/init.lua
deleted file mode 100644 (file)
index 3803994..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-
-core.log("info", "Initializing Asynchronous environment")
-
-function core.job_processor(func, serialized_param)
-       local param = core.deserialize(serialized_param)
-
-       local retval = core.serialize(func(param))
-
-       return retval or core.serialize(nil)
-end
-
diff --git a/builtin/async/mainmenu.lua b/builtin/async/mainmenu.lua
new file mode 100644 (file)
index 0000000..0e9c222
--- /dev/null
@@ -0,0 +1,9 @@
+core.log("info", "Initializing asynchronous environment")
+
+function core.job_processor(func, serialized_param)
+       local param = core.deserialize(serialized_param)
+
+       local retval = core.serialize(func(param))
+
+       return retval or core.serialize(nil)
+end
index f17188b842b6c1de422a3aacba5a573838fa24ba..637a22556cd0a293484bbeb37c03fdec6a221c30 100644 (file)
@@ -1,4 +1,3 @@
-
 core.callback_origins = {}
 
 local getinfo = debug.getinfo
index e20f292f0240ab69e83e0369c1ae1f29fe775354..bce2625370cd63f80ffdca83497895e937c9ec90 100644 (file)
@@ -37,7 +37,14 @@ function core.after(after, func, ...)
                arg = {...},
                mod_origin = core.get_last_run_mod(),
        }
+
        jobs[#jobs + 1] = new_job
        time_next = math.min(time_next, expire)
-       return { cancel = function() new_job.func = function() end end }
+
+       return {
+               cancel = function()
+                       new_job.func = function() end
+                       new_job.args = {}
+               end
+       }
 end
index 62f9eacd06c93525fbdeeb377a1357ec1219d54c..817f1f526186d2657ba9084731d12adf844ec8d5 100644 (file)
@@ -6,6 +6,42 @@ local S = core.get_translator("__builtin")
 
 core.registered_chatcommands = {}
 
+-- Interpret the parameters of a command, separating options and arguments.
+-- Input: command, param
+--   command: name of command
+--   param: parameters of command
+-- Returns: opts, args
+--   opts is a string of option letters, or false on error
+--   args is an array with the non-option arguments in order, or an error message
+-- Example: for this command line:
+--      /command a b -cd e f -g
+-- the function would receive:
+--      a b -cd e f -g
+-- and it would return:
+--     "cdg", {"a", "b", "e", "f"}
+-- Negative numbers are taken as arguments. Long options (--option) are
+-- currently rejected as reserved.
+local function getopts(command, param)
+       local opts = ""
+       local args = {}
+       for match in param:gmatch("%S+") do
+               if match:byte(1) == 45 then -- 45 = '-'
+                       local second = match:byte(2)
+                       if second == 45 then
+                               return false, S("Invalid parameters (see /help @1).", command)
+                       elseif second and (second < 48 or second > 57) then -- 48 = '0', 57 = '9'
+                               opts = opts .. match:sub(2)
+                       else
+                               -- numeric, add it to args
+                               args[#args + 1] = match
+                       end
+               else
+                       args[#args + 1] = match
+               end
+       end
+       return opts, args
+end
+
 function core.register_chatcommand(cmd, def)
        def = def or {}
        def.params = def.params or ""
@@ -78,22 +114,30 @@ if INIT == "client" then
        end
 end
 
+local function format_help_line(cmd, def)
+       local cmd_marker = INIT == "client" and "." or "/"
+       local msg = core.colorize("#00ffff", cmd_marker .. cmd)
+       if def.params and def.params ~= "" then
+               msg = msg .. " " .. def.params
+       end
+       if def.description and def.description ~= "" then
+               msg = msg .. ": " .. def.description
+       end
+       return msg
+end
+
 local function do_help_cmd(name, param)
-       local function format_help_line(cmd, def)
-               local cmd_marker = "/"
-               if INIT == "client" then
-                       cmd_marker = "."
-               end
-               local msg = core.colorize("#00ffff", cmd_marker .. cmd)
-               if def.params and def.params ~= "" then
-                       msg = msg .. " " .. def.params
-               end
-               if def.description and def.description ~= "" then
-                       msg = msg .. ": " .. def.description
-               end
-               return msg
+       local opts, args = getopts("help", param)
+       if not opts then
+               return false, args
+       end
+       if #args > 1 then
+               return false, S("Too many arguments, try using just /help <command>")
        end
-       if param == "" then
+       local use_gui = INIT ~= "client" and core.get_player_by_name(name)
+       use_gui = use_gui and not opts:find("t")
+
+       if #args == 0 and not use_gui then
                local cmds = {}
                for cmd, def in pairs(core.registered_chatcommands) do
                        if INIT == "client" or core.check_player_privs(name, def.privs) then
@@ -116,7 +160,10 @@ local function do_help_cmd(name, param)
                                .. "everything.")
                end
                return true, msg
-       elseif param == "all" then
+       elseif #args == 0 or (args[1] == "all" and use_gui) then
+               core.show_general_help_formspec(name)
+               return true
+       elseif args[1] == "all" then
                local cmds = {}
                for cmd, def in pairs(core.registered_chatcommands) do
                        if INIT == "client" or core.check_player_privs(name, def.privs) then
@@ -131,7 +178,11 @@ local function do_help_cmd(name, param)
                        msg = core.gettext("Available commands:")
                end
                return true, msg.."\n"..table.concat(cmds, "\n")
-       elseif INIT == "game" and param == "privs" then
+       elseif INIT == "game" and args[1] == "privs" then
+               if use_gui then
+                       core.show_privs_help_formspec(name)
+                       return true
+               end
                local privs = {}
                for priv, def in pairs(core.registered_privileges) do
                        privs[#privs + 1] = priv .. ": " .. def.description
@@ -139,7 +190,7 @@ local function do_help_cmd(name, param)
                table.sort(privs)
                return true, S("Available privileges:").."\n"..table.concat(privs, "\n")
        else
-               local cmd = param
+               local cmd = args[1]
                local def = core.registered_chatcommands[cmd]
                if not def then
                        local msg
@@ -165,8 +216,8 @@ if INIT == "client" then
        })
 else
        core.register_chatcommand("help", {
-               params = S("[all | privs | <cmd>]"),
-               description = S("Get help for commands or list privileges"),
+               params = S("[all | privs | <cmd>] [-t]"),
+               description = S("Get help for commands or list privileges (-t: output in chat)"),
                func = do_help_cmd,
        })
 end
index e814b4c43c8e50bba5b1bd435941b1f3461f0fe0..3405263bf42506489b04a4df1818776f418ac6cf 100644 (file)
@@ -125,30 +125,12 @@ core.register_on_player_receive_fields(function(player, formname, fields)
        end
 end)
 
-
-local help_command = core.registered_chatcommands["help"]
-local old_help_func = help_command.func
-
-help_command.func = function(name, param)
-       local admin = core.settings:get("name")
-
-       -- If the admin ran help, put the output in the chat buffer as well to
-       -- work with the server terminal
-       if param == "privs" then
-               core.show_formspec(name, "__builtin:help_privs",
-                       build_privs_formspec(name))
-               if name ~= admin then
-                       return true
-               end
-       end
-       if param == "" or param == "all" then
-               core.show_formspec(name, "__builtin:help_cmds",
-                       build_chatcommands_formspec(name))
-               if name ~= admin then
-                       return true
-               end
-       end
-
-       return old_help_func(name, param)
+function core.show_general_help_formspec(name)
+       core.show_formspec(name, "__builtin:help_cmds",
+               build_chatcommands_formspec(name))
 end
 
+function core.show_privs_help_formspec(name)
+       core.show_formspec(name, "__builtin:help_privs",
+               build_privs_formspec(name))
+end
index e4bc056d9ff424f9b83d9a439bbc5438200cf5dd..542b2040d6579df334fe444489b3c0ebb41a566b 100644 (file)
@@ -543,7 +543,7 @@ if INIT == "mainmenu" then
        end
 end
 
-if INIT == "client" or INIT == "mainmenu" then
+if core.gettext then -- for client and mainmenu
        function fgettext_ne(text, ...)
                text = core.gettext(text)
                local arg = {n=select('#', ...), ...}
index ccde9676b3af202bbba0f13b6b11b306a0e70287..f46234dc6b9006a302f2ed7d516b7ceaf15bebd4 100644 (file)
@@ -1,8 +1,3 @@
-
--- Always warn when creating a global variable, even outside of a function.
--- This ignores mod namespaces (variables with the same name as the current mod).
-local WARN_INIT = false
-
 local getinfo = debug.getinfo
 
 function core.global_exists(name)
@@ -33,11 +28,6 @@ function meta:__newindex(name, value)
                end
                declared[name] = true
        end
-       -- Ignore mod namespaces
-       if WARN_INIT and name ~= core.get_current_modname() then
-               core.log("warning", ("Global variable %q created at %s.")
-                       :format(name, desc))
-       end
        rawset(self, name, value)
 end
 
@@ -54,4 +44,3 @@ function meta:__index(name)
 end
 
 setmetatable(_G, meta)
-
index b16987f0b6a011d4fdd0ec2f0fa8d5f3c995446a..b112368605886aed85a7de325eecff02f909d534 100644 (file)
@@ -1,4 +1,5 @@
 _G.core = {}
+_G.vector = {metatable = {}}
 dofile("builtin/common/vector.lua")
 dofile("builtin/common/misc_helpers.lua")
 
index e46b7dcc529ce07482f357dfd953bf98b05c3338..69b2b567c68c9d34859a5d0b75ece67d350d7e82 100644 (file)
@@ -1,4 +1,5 @@
 _G.core = {}
+_G.vector = {metatable = {}}
 
 _G.setfenv = require 'busted.compatibility'.setfenv
 
index 2a50e2889f9bf717ba77bc029412129ccff04370..6a0b81a89128de8f3e6edb7e709fa7c9e5339b36 100644 (file)
@@ -1,4 +1,4 @@
-_G.vector = {}
+_G.vector = {metatable = {}}
 dofile("builtin/common/vector.lua")
 
 describe("vector", function()
@@ -128,6 +128,14 @@ describe("vector", function()
                assert.equal(vector.new(4.1, 5.9, 5.5), a:apply(f))
        end)
 
+       it("combine()", function()
+               local a = vector.new(1, 2, 3)
+               local b = vector.new(3, 2, 1)
+               assert.equal(vector.add(a, b), vector.combine(a, b, function(x, y) return x + y end))
+               assert.equal(vector.new(3, 2, 3), vector.combine(a, b, math.max))
+               assert.equal(vector.new(1, 2, 1), vector.combine(a, b, math.min))
+       end)
+
        it("equals()", function()
                local function assertE(a, b)
                        assert.is_true(vector.equals(a, b))
@@ -300,6 +308,7 @@ describe("vector", function()
 
        it("from_string()", function()
                local v = vector.new(1, 2, 3.14)
+               assert.is_true(vector.check(vector.from_string("(1, 2, 3.14)")))
                assert.same({v, 13}, {vector.from_string("(1, 2, 3.14)")})
                assert.same({v, 12}, {vector.from_string("(1,2 ,3.14)")})
                assert.same({v, 12}, {vector.from_string("(1,2,3.14,)")})
index 02fc1bdee0cfbde2d4aaa94086db2d87047d061f..a08472e322c7b42513f084e9f94560791e778e20 100644 (file)
@@ -6,10 +6,8 @@ Note: The vector.*-functions must be able to accept old vectors that had no meta
 -- localize functions
 local setmetatable = setmetatable
 
-vector = {}
-
-local metatable = {}
-vector.metatable = metatable
+-- vector.metatable is set by C++.
+local metatable = vector.metatable
 
 local xyz = {"x", "y", "z"}
 
@@ -61,7 +59,7 @@ function vector.from_string(s, init)
        if not (x and y and z) then
                return nil
        end
-       return {x = x, y = y, z = z}, np
+       return fast_new(x, y, z), np
 end
 
 function vector.to_string(v)
@@ -112,6 +110,14 @@ function vector.apply(v, func)
        )
 end
 
+function vector.combine(a, b, func)
+       return fast_new(
+               func(a.x, b.x),
+               func(a.y, b.y),
+               func(a.z, b.z)
+       )
+end
+
 function vector.distance(a, b)
        local x = a.x - b.x
        local y = a.y - b.y
index 976659ed364bda029f57496eae169727225d57a2..13f9cbec2554eb571d063241934b4d7296733ad4 100644 (file)
@@ -63,7 +63,7 @@ function ui.update()
        -- handle errors
        if gamedata ~= nil and gamedata.reconnect_requested then
                local error_message = core.formspec_escape(
-                               gamedata.errormessage or "<none available>")
+                               gamedata.errormessage or fgettext("<none available>"))
                formspec = {
                        "size[14,8]",
                        "real_coordinates[true]",
diff --git a/builtin/game/async.lua b/builtin/game/async.lua
new file mode 100644 (file)
index 0000000..469f179
--- /dev/null
@@ -0,0 +1,22 @@
+
+core.async_jobs = {}
+
+function core.async_event_handler(jobid, retval)
+       local callback = core.async_jobs[jobid]
+       assert(type(callback) == "function")
+       callback(unpack(retval, 1, retval.n))
+       core.async_jobs[jobid] = nil
+end
+
+function core.handle_async(func, callback, ...)
+       assert(type(func) == "function" and type(callback) == "function",
+               "Invalid minetest.handle_async invocation")
+       local args = {n = select("#", ...), ...}
+       local mod_origin = core.get_last_run_mod()
+
+       local jobid = core.do_async_callback(func, args, mod_origin)
+       core.async_jobs[jobid] = callback
+
+       return true
+end
+
index 99296f78247612300c8f3b8984b444577ea14709..c4fb6314e564e2f90e6e7bd9e7190b4863d5040d 100644 (file)
@@ -310,12 +310,7 @@ local function handle_revoke_command(caller, revokename, revokeprivstr)
                        and revokename == core.settings:get("name")
                        and revokename ~= ""
        if revokeprivstr == "all" then
-               revokeprivs = privs
-               privs = {}
-       else
-               for priv, _ in pairs(revokeprivs) do
-                       privs[priv] = nil
-               end
+               revokeprivs = table.copy(privs)
        end
 
        local privs_unknown = ""
@@ -332,7 +327,10 @@ local function handle_revoke_command(caller, revokename, revokeprivstr)
                end
                local def = core.registered_privileges[priv]
                if not def then
-                       privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n"
+                       -- Old/removed privileges might still be granted to certain players
+                       if not privs[priv] then
+                               privs_unknown = privs_unknown .. S("Unknown privilege: @1", priv) .. "\n"
+                       end
                elseif is_singleplayer and def.give_to_singleplayer then
                        irrevokable[priv] = true
                elseif is_admin and def.give_to_admin then
@@ -359,19 +357,22 @@ local function handle_revoke_command(caller, revokename, revokeprivstr)
        end
 
        local revokecount = 0
-
-       core.set_player_privs(revokename, privs)
        for priv, _ in pairs(revokeprivs) do
-               -- call the on_revoke callbacks
-               core.run_priv_callbacks(revokename, priv, caller, "revoke")
+               privs[priv] = nil
                revokecount = revokecount + 1
        end
-       local new_privs = core.get_player_privs(revokename)
 
        if revokecount == 0 then
                return false, S("No privileges were revoked.")
        end
 
+       core.set_player_privs(revokename, privs)
+       for priv, _ in pairs(revokeprivs) do
+               -- call the on_revoke callbacks
+               core.run_priv_callbacks(revokename, priv, caller, "revoke")
+       end
+       local new_privs = core.get_player_privs(revokename)
+
        core.log("action", caller..' revoked ('
                        ..core.privs_to_string(revokeprivs, ', ')
                        ..') privileges from '..revokename)
@@ -524,7 +525,7 @@ end
 
 -- Teleports player <name> to <p> if possible
 local function teleport_to_pos(name, p)
-       local lm = 31000
+       local lm = 31007 -- equals MAX_MAP_GENERATION_LIMIT in C++
        if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm
                        or p.z < -lm or p.z > lm then
                return false, S("Cannot teleport out of map bounds!")
@@ -621,6 +622,10 @@ core.register_chatcommand("set", {
 
                setname, setvalue = string.match(param, "([^ ]+) (.+)")
                if setname and setvalue then
+                       if setname:sub(1, 7) == "secure." then
+                               return false, S("Failed. Cannot modify secure settings. "
+                                       .. "Edit the settings file manually.")
+                       end
                        if not core.settings:get(setname) then
                                return false, S("Failed. Use '/set -n <name> <value>' "
                                        .. "to create a new setting.")
@@ -1034,12 +1039,11 @@ core.register_chatcommand("time", {
                end
                local hour, minute = param:match("^(%d+):(%d+)$")
                if not hour then
-                       local new_time = tonumber(param)
-                       if not new_time then
-                               return false, S("Invalid time.")
+                       local new_time = tonumber(param) or -1
+                       if new_time ~= new_time or new_time < 0 or new_time > 24000 then
+                               return false, S("Invalid time (must be between 0 and 24000).")
                        end
-                       -- Backward compatibility.
-                       core.set_timeofday((new_time % 24000) / 24000)
+                       core.set_timeofday(new_time / 24000)
                        core.log("action", name .. " sets time to " .. new_time)
                        return true, S("Time of day changed.")
                end
@@ -1283,7 +1287,7 @@ local function handle_kill_command(killer, victim)
                        return false, S("@1 is already dead.", victim)
                end
        end
-       if not killer == victim then
+       if killer ~= victim then
                core.log("action", string.format("%s killed %s", killer, victim))
        end
        -- Kill victim
index 583ef50926baa70a5b9c935dd4edda32b676181f..0d55bb01f80bcce9b6e0db3675179069bcfe110e 100644 (file)
@@ -22,6 +22,7 @@ core.features = {
        degrotate_240_steps = true,
        abm_min_max_y = true,
        dynamic_add_media_table = true,
+       get_sky_as_table = true,
 }
 
 function core.has_feature(arg)
index 9a9966d7e57ab8f2f999c2f6f74c0b54e9f41fe4..b9ab97b58251078a3f97523866db2204f8727baa 100644 (file)
@@ -8,6 +8,7 @@ local gamepath   = scriptpath .. "game".. DIR_DELIM
 local builtin_shared = {}
 
 dofile(gamepath .. "constants.lua")
+dofile(gamepath .. "item_s.lua")
 assert(loadfile(gamepath .. "item.lua"))(builtin_shared)
 dofile(gamepath .. "register.lua")
 
@@ -19,6 +20,7 @@ dofile(commonpath .. "after.lua")
 dofile(commonpath .. "voxelarea.lua")
 dofile(gamepath .. "item_entity.lua")
 dofile(gamepath .. "deprecated.lua")
+dofile(gamepath .. "misc_s.lua")
 dofile(gamepath .. "misc.lua")
 dofile(gamepath .. "privileges.lua")
 dofile(gamepath .. "auth.lua")
@@ -32,5 +34,6 @@ dofile(gamepath .. "features.lua")
 dofile(gamepath .. "forceloading.lua")
 dofile(gamepath .. "statbars.lua")
 dofile(gamepath .. "knockback.lua")
+dofile(gamepath .. "async.lua")
 
 profiler = nil
index 92818b177f27c3b54c4890abef2421758ab826f0..5543e9a3ff2604fdbbeab2aa8c5d8f7bf8d91df8 100644 (file)
@@ -15,144 +15,19 @@ end
 -- Item definition helpers
 --
 
-function core.dir_to_facedir(dir, is6d)
-       --account for y if requested
-       if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
-
-               --from above
-               if dir.y < 0 then
-                       if math.abs(dir.x) > math.abs(dir.z) then
-                               if dir.x < 0 then
-                                       return 19
-                               else
-                                       return 13
-                               end
-                       else
-                               if dir.z < 0 then
-                                       return 10
-                               else
-                                       return 4
-                               end
-                       end
-
-               --from below
-               else
-                       if math.abs(dir.x) > math.abs(dir.z) then
-                               if dir.x < 0 then
-                                       return 15
-                               else
-                                       return 17
-                               end
-                       else
-                               if dir.z < 0 then
-                                       return 6
-                               else
-                                       return 8
-                               end
-                       end
-               end
-
-       --otherwise, place horizontally
-       elseif math.abs(dir.x) > math.abs(dir.z) then
-               if dir.x < 0 then
-                       return 3
-               else
-                       return 1
-               end
-       else
-               if dir.z < 0 then
-                       return 2
-               else
-                       return 0
-               end
-       end
-end
-
--- Table of possible dirs
-local facedir_to_dir = {
-       vector.new( 0,  0,  1),
-       vector.new( 1,  0,  0),
-       vector.new( 0,  0, -1),
-       vector.new(-1,  0,  0),
-       vector.new( 0, -1,  0),
-       vector.new( 0,  1,  0),
-}
--- Mapping from facedir value to index in facedir_to_dir.
-local facedir_to_dir_map = {
-       [0]=1, 2, 3, 4,
-       5, 2, 6, 4,
-       6, 2, 5, 4,
-       1, 5, 3, 6,
-       1, 6, 3, 5,
-       1, 4, 3, 2,
-}
-function core.facedir_to_dir(facedir)
-       return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
-end
-
-function core.dir_to_wallmounted(dir)
-       if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
-               if dir.y < 0 then
-                       return 1
-               else
-                       return 0
-               end
-       elseif math.abs(dir.x) > math.abs(dir.z) then
-               if dir.x < 0 then
-                       return 3
-               else
-                       return 2
-               end
-       else
-               if dir.z < 0 then
-                       return 5
-               else
-                       return 4
+function core.get_pointed_thing_position(pointed_thing, above)
+       if pointed_thing.type == "node" then
+               if above then
+                       -- The position where a node would be placed
+                       return pointed_thing.above
                end
+               -- The position where a node would be dug
+               return pointed_thing.under
+       elseif pointed_thing.type == "object" then
+               return pointed_thing.ref and pointed_thing.ref:get_pos()
        end
 end
 
--- table of dirs in wallmounted order
-local wallmounted_to_dir = {
-       [0] = vector.new( 0,  1,  0),
-       vector.new( 0, -1,  0),
-       vector.new( 1,  0,  0),
-       vector.new(-1,  0,  0),
-       vector.new( 0,  0,  1),
-       vector.new( 0,  0, -1),
-}
-function core.wallmounted_to_dir(wallmounted)
-       return wallmounted_to_dir[wallmounted % 8]
-end
-
-function core.dir_to_yaw(dir)
-       return -math.atan2(dir.x, dir.z)
-end
-
-function core.yaw_to_dir(yaw)
-       return vector.new(-math.sin(yaw), 0, math.cos(yaw))
-end
-
-function core.is_colored_paramtype(ptype)
-       return (ptype == "color") or (ptype == "colorfacedir") or
-               (ptype == "colorwallmounted") or (ptype == "colordegrotate")
-end
-
-function core.strip_param2_color(param2, paramtype2)
-       if not core.is_colored_paramtype(paramtype2) then
-               return nil
-       end
-       if paramtype2 == "colorfacedir" then
-               param2 = math.floor(param2 / 32) * 32
-       elseif paramtype2 == "colorwallmounted" then
-               param2 = math.floor(param2 / 8) * 8
-       elseif paramtype2 == "colordegrotate" then
-               param2 = math.floor(param2 / 32) * 32
-       end
-       -- paramtype2 == "color" requires no modification.
-       return param2
-end
-
 local function has_all_groups(tbl, required_groups)
        if type(required_groups) == "string" then
                return (tbl[required_groups] or 0) ~= 0
@@ -477,34 +352,41 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed
                        return result
                end
        end
+       -- read definition before potentially emptying the stack
        local def = itemstack:get_definition()
-       if itemstack:take_item() ~= nil then
-               user:set_hp(user:get_hp() + hp_change)
-
-               if def and def.sound and def.sound.eat then
-                       core.sound_play(def.sound.eat, {
-                               pos = user:get_pos(),
-                               max_hear_distance = 16
-                       }, true)
-               end
+       if itemstack:take_item():is_empty() then
+               return itemstack
+       end
+
+       if def and def.sound and def.sound.eat then
+               core.sound_play(def.sound.eat, {
+                       pos = user:get_pos(),
+                       max_hear_distance = 16
+               }, true)
+       end
 
-               if replace_with_item then
-                       if itemstack:is_empty() then
-                               itemstack:add_item(replace_with_item)
+       -- Changing hp might kill the player causing mods to do who-knows-what to the
+       -- inventory, so do this before set_hp().
+       if replace_with_item then
+               if itemstack:is_empty() then
+                       itemstack:add_item(replace_with_item)
+               else
+                       local inv = user:get_inventory()
+                       -- Check if inv is null, since non-players don't have one
+                       if inv and inv:room_for_item("main", {name=replace_with_item}) then
+                               inv:add_item("main", replace_with_item)
                        else
-                               local inv = user:get_inventory()
-                               -- Check if inv is null, since non-players don't have one
-                               if inv and inv:room_for_item("main", {name=replace_with_item}) then
-                                       inv:add_item("main", replace_with_item)
-                               else
-                                       local pos = user:get_pos()
-                                       pos.y = math.floor(pos.y + 0.5)
-                                       core.add_item(pos, replace_with_item)
-                               end
+                               local pos = user:get_pos()
+                               pos.y = math.floor(pos.y + 0.5)
+                               core.add_item(pos, replace_with_item)
                        end
                end
        end
-       return itemstack
+       user:set_wielded_item(itemstack)
+
+       user:set_hp(user:get_hp() + hp_change)
+
+       return nil -- don't overwrite wield item a second time
 end
 
 function core.item_eat(hp_change, replace_with_item)
@@ -585,7 +467,7 @@ function core.node_dig(pos, node, digger)
        if wielded then
                local wdef = wielded:get_definition()
                local tp = wielded:get_tool_capabilities()
-               local dp = core.get_dig_params(def and def.groups, tp)
+               local dp = core.get_dig_params(def and def.groups, tp, wielded:get_wear())
                if wdef and wdef.after_use then
                        wielded = wdef.after_use(wielded, digger, node, dp) or wielded
                else
@@ -647,9 +529,7 @@ function core.node_dig(pos, node, digger)
        -- Run script hook
        for _, callback in ipairs(core.registered_on_dignodes) do
                local origin = core.callback_origins[callback]
-               if origin then
-                       core.set_last_run_mod(origin.mod)
-               end
+               core.set_last_run_mod(origin.mod)
 
                -- Copy pos and node because callback can modify them
                local pos_copy = vector.new(pos)
index 9b1b23bfd14d6013297190013b8784dbfcfbf367..53f98a7c73c126e9905ef340d3af4038d0bfaea7 100644 (file)
@@ -58,17 +58,21 @@ core.register_entity(":__builtin:item", {
                local glow = def and def.light_source and
                        math.floor(def.light_source / 2 + 0.5)
 
+               local size_bias = 1e-3 * math.random() -- small random bias to counter Z-fighting
+               local c = {-size, -size, -size, size, size, size}
                self.object:set_properties({
                        is_visible = true,
                        visual = "wielditem",
                        textures = {itemname},
-                       visual_size = {x = size, y = size},
-                       collisionbox = {-size, -size, -size, size, size, size},
+                       visual_size = {x = size + size_bias, y = size + size_bias},
+                       collisionbox = c,
                        automatic_rotate = math.pi * 0.5 * 0.2 / size,
                        wield_item = self.itemstring,
                        glow = glow,
                })
 
+               -- cache for usage in on_step
+               self._collisionbox = c
        end,
 
        get_staticdata = function(self)
@@ -93,6 +97,7 @@ core.register_entity(":__builtin:item", {
                self.object:set_armor_groups({immortal = 1})
                self.object:set_velocity({x = 0, y = 2, z = 0})
                self.object:set_acceleration({x = 0, y = -gravity, z = 0})
+               self._collisionbox = self.initial_properties.collisionbox
                self:set_item()
        end,
 
@@ -163,7 +168,7 @@ core.register_entity(":__builtin:item", {
                local pos = self.object:get_pos()
                local node = core.get_node_or_nil({
                        x = pos.x,
-                       y = pos.y + self.object:get_properties().collisionbox[2] - 0.05,
+                       y = pos.y + self._collisionbox[2] - 0.05,
                        z = pos.z
                })
                -- Delete in 'ignore' nodes
@@ -176,7 +181,7 @@ core.register_entity(":__builtin:item", {
                if self.force_out then
                        -- This code runs after the entity got a push from the is_stuck code.
                        -- It makes sure the entity is entirely outside the solid node
-                       local c = self.object:get_properties().collisionbox
+                       local c = self._collisionbox
                        local s = self.force_out_start
                        local f = self.force_out
                        local ok = (f.x > 0 and pos.x + c[1] > s.x + 0.5) or
diff --git a/builtin/game/item_s.lua b/builtin/game/item_s.lua
new file mode 100644 (file)
index 0000000..a51cd0a
--- /dev/null
@@ -0,0 +1,156 @@
+-- Minetest: builtin/item_s.lua
+-- The distinction of what goes here is a bit tricky, basically it's everything
+-- that does not (directly or indirectly) need access to ServerEnvironment,
+-- Server or writable access to IGameDef on the engine side.
+-- (The '_s' stands for standalone.)
+
+--
+-- Item definition helpers
+--
+
+function core.inventorycube(img1, img2, img3)
+       img2 = img2 or img1
+       img3 = img3 or img1
+       return "[inventorycube"
+                       .. "{" .. img1:gsub("%^", "&")
+                       .. "{" .. img2:gsub("%^", "&")
+                       .. "{" .. img3:gsub("%^", "&")
+end
+
+function core.dir_to_facedir(dir, is6d)
+       --account for y if requested
+       if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
+
+               --from above
+               if dir.y < 0 then
+                       if math.abs(dir.x) > math.abs(dir.z) then
+                               if dir.x < 0 then
+                                       return 19
+                               else
+                                       return 13
+                               end
+                       else
+                               if dir.z < 0 then
+                                       return 10
+                               else
+                                       return 4
+                               end
+                       end
+
+               --from below
+               else
+                       if math.abs(dir.x) > math.abs(dir.z) then
+                               if dir.x < 0 then
+                                       return 15
+                               else
+                                       return 17
+                               end
+                       else
+                               if dir.z < 0 then
+                                       return 6
+                               else
+                                       return 8
+                               end
+                       end
+               end
+
+       --otherwise, place horizontally
+       elseif math.abs(dir.x) > math.abs(dir.z) then
+               if dir.x < 0 then
+                       return 3
+               else
+                       return 1
+               end
+       else
+               if dir.z < 0 then
+                       return 2
+               else
+                       return 0
+               end
+       end
+end
+
+-- Table of possible dirs
+local facedir_to_dir = {
+       vector.new( 0,  0,  1),
+       vector.new( 1,  0,  0),
+       vector.new( 0,  0, -1),
+       vector.new(-1,  0,  0),
+       vector.new( 0, -1,  0),
+       vector.new( 0,  1,  0),
+}
+-- Mapping from facedir value to index in facedir_to_dir.
+local facedir_to_dir_map = {
+       [0]=1, 2, 3, 4,
+       5, 2, 6, 4,
+       6, 2, 5, 4,
+       1, 5, 3, 6,
+       1, 6, 3, 5,
+       1, 4, 3, 2,
+}
+function core.facedir_to_dir(facedir)
+       return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
+end
+
+function core.dir_to_wallmounted(dir)
+       if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
+               if dir.y < 0 then
+                       return 1
+               else
+                       return 0
+               end
+       elseif math.abs(dir.x) > math.abs(dir.z) then
+               if dir.x < 0 then
+                       return 3
+               else
+                       return 2
+               end
+       else
+               if dir.z < 0 then
+                       return 5
+               else
+                       return 4
+               end
+       end
+end
+
+-- table of dirs in wallmounted order
+local wallmounted_to_dir = {
+       [0] = vector.new( 0,  1,  0),
+       vector.new( 0, -1,  0),
+       vector.new( 1,  0,  0),
+       vector.new(-1,  0,  0),
+       vector.new( 0,  0,  1),
+       vector.new( 0,  0, -1),
+}
+function core.wallmounted_to_dir(wallmounted)
+       return wallmounted_to_dir[wallmounted % 8]
+end
+
+function core.dir_to_yaw(dir)
+       return -math.atan2(dir.x, dir.z)
+end
+
+function core.yaw_to_dir(yaw)
+       return vector.new(-math.sin(yaw), 0, math.cos(yaw))
+end
+
+function core.is_colored_paramtype(ptype)
+       return (ptype == "color") or (ptype == "colorfacedir") or
+               (ptype == "colorwallmounted") or (ptype == "colordegrotate")
+end
+
+function core.strip_param2_color(param2, paramtype2)
+       if not core.is_colored_paramtype(paramtype2) then
+               return nil
+       end
+       if paramtype2 == "colorfacedir" then
+               param2 = math.floor(param2 / 32) * 32
+       elseif paramtype2 == "colorwallmounted" then
+               param2 = math.floor(param2 / 8) * 8
+       elseif paramtype2 == "colordegrotate" then
+               param2 = math.floor(param2 / 32) * 32
+       end
+       -- paramtype2 == "color" requires no modification.
+       return param2
+end
index 63d64817c7579b671a1e54eddf49451486bede1c..997b1894a8acda38040e5e62d6e7ffa6be62fed8 100644 (file)
@@ -6,6 +6,16 @@ local S = core.get_translator("__builtin")
 -- Misc. API functions
 --
 
+-- @spec core.kick_player(String, String) :: Boolean
+function core.kick_player(player_name, reason)
+       if type(reason) == "string" then
+               reason = "Kicked: " .. reason
+       else
+               reason = "Kicked."
+       end
+       return core.disconnect_player(player_name, reason)
+end
+
 function core.check_player_privs(name, ...)
        if core.is_player(name) then
                name = name:get_player_name()
@@ -111,53 +121,6 @@ function core.get_player_radius_area(player_name, radius)
 end
 
 
-function core.hash_node_position(pos)
-       return (pos.z + 32768) * 65536 * 65536
-                + (pos.y + 32768) * 65536
-                +  pos.x + 32768
-end
-
-
-function core.get_position_from_hash(hash)
-       local x = (hash % 65536) - 32768
-       hash  = math.floor(hash / 65536)
-       local y = (hash % 65536) - 32768
-       hash  = math.floor(hash / 65536)
-       local z = (hash % 65536) - 32768
-       return vector.new(x, y, z)
-end
-
-
-function core.get_item_group(name, group)
-       if not core.registered_items[name] or not
-                       core.registered_items[name].groups[group] then
-               return 0
-       end
-       return core.registered_items[name].groups[group]
-end
-
-
-function core.get_node_group(name, group)
-       core.log("deprecated", "Deprecated usage of get_node_group, use get_item_group instead")
-       return core.get_item_group(name, group)
-end
-
-
-function core.setting_get_pos(name)
-       local value = core.settings:get(name)
-       if not value then
-               return nil
-       end
-       return core.string_to_pos(value)
-end
-
-
--- See l_env.cpp for the other functions
-function core.get_artificial_light(param1)
-       return math.floor(param1 / 16)
-end
-
-
 -- To be overriden by protection mods
 
 function core.is_protected(pos, name)
@@ -240,7 +203,7 @@ end
 
 -- HTTP callback interface
 
-function core.http_add_fetch(httpenv)
+core.set_http_api_lua(function(httpenv)
        httpenv.fetch = function(req, callback)
                local handle = httpenv.fetch_async(req)
 
@@ -256,7 +219,8 @@ function core.http_add_fetch(httpenv)
        end
 
        return httpenv
-end
+end)
+core.set_http_api_lua = nil
 
 
 function core.close_formspec(player_name, formname)
@@ -273,40 +237,30 @@ end
 core.dynamic_media_callbacks = {}
 
 
--- PNG encoder safety wrapper
-
-local o_encode_png = core.encode_png
-function core.encode_png(width, height, data, compression)
-       if type(width) ~= "number" then
-               error("Incorrect type for 'width', expected number, got " .. type(width))
-       end
-       if type(height) ~= "number" then
-               error("Incorrect type for 'height', expected number, got " .. type(height))
-       end
-
-       local expected_byte_count = width * height * 4
+-- Transfer of certain globals into async environment
+-- see builtin/async/game.lua for the other side
 
-       if type(data) ~= "table" and type(data) ~= "string" then
-               error("Incorrect type for 'height', expected table or string, got " .. type(height))
+local function copy_filtering(t, seen)
+       if type(t) == "userdata" or type(t) == "function" then
+               return true -- don't use nil so presence can still be detected
+       elseif type(t) ~= "table" then
+               return t
        end
-
-       local data_length = type(data) == "table" and #data * 4 or string.len(data)
-
-       if data_length ~= expected_byte_count then
-               error(string.format(
-                       "Incorrect length of 'data', width and height imply %d bytes but %d were provided",
-                       expected_byte_count,
-                       data_length
-               ))
-       end
-
-       if type(data) == "table" then
-               local dataBuf = {}
-               for i = 1, #data do
-                       dataBuf[i] = core.colorspec_to_bytes(data[i])
-               end
-               data = table.concat(dataBuf)
+       local n = {}
+       seen = seen or {}
+       seen[t] = n
+       for k, v in pairs(t) do
+               local k_ = seen[k] or copy_filtering(k, seen)
+               local v_ = seen[v] or copy_filtering(v, seen)
+               n[k_] = v_
        end
+       return n
+end
 
-       return o_encode_png(width, height, data, compression or 6)
+function core.get_globals_to_transfer()
+       local all = {
+               registered_items = copy_filtering(core.registered_items),
+               registered_aliases = core.registered_aliases,
+       }
+       return all
 end
diff --git a/builtin/game/misc_s.lua b/builtin/game/misc_s.lua
new file mode 100644 (file)
index 0000000..67a0ec6
--- /dev/null
@@ -0,0 +1,93 @@
+-- Minetest: builtin/misc_s.lua
+-- The distinction of what goes here is a bit tricky, basically it's everything
+-- that does not (directly or indirectly) need access to ServerEnvironment,
+-- Server or writable access to IGameDef on the engine side.
+-- (The '_s' stands for standalone.)
+
+--
+-- Misc. API functions
+--
+
+function core.hash_node_position(pos)
+       return (pos.z + 32768) * 65536 * 65536
+                + (pos.y + 32768) * 65536
+                +  pos.x + 32768
+end
+
+
+function core.get_position_from_hash(hash)
+       local x = (hash % 65536) - 32768
+       hash  = math.floor(hash / 65536)
+       local y = (hash % 65536) - 32768
+       hash  = math.floor(hash / 65536)
+       local z = (hash % 65536) - 32768
+       return vector.new(x, y, z)
+end
+
+
+function core.get_item_group(name, group)
+       if not core.registered_items[name] or not
+                       core.registered_items[name].groups[group] then
+               return 0
+       end
+       return core.registered_items[name].groups[group]
+end
+
+
+function core.get_node_group(name, group)
+       core.log("deprecated", "Deprecated usage of get_node_group, use get_item_group instead")
+       return core.get_item_group(name, group)
+end
+
+
+function core.setting_get_pos(name)
+       local value = core.settings:get(name)
+       if not value then
+               return nil
+       end
+       return core.string_to_pos(value)
+end
+
+
+-- See l_env.cpp for the other functions
+function core.get_artificial_light(param1)
+       return math.floor(param1 / 16)
+end
+
+-- PNG encoder safety wrapper
+
+local o_encode_png = core.encode_png
+function core.encode_png(width, height, data, compression)
+       if type(width) ~= "number" then
+               error("Incorrect type for 'width', expected number, got " .. type(width))
+       end
+       if type(height) ~= "number" then
+               error("Incorrect type for 'height', expected number, got " .. type(height))
+       end
+
+       local expected_byte_count = width * height * 4
+
+       if type(data) ~= "table" and type(data) ~= "string" then
+               error("Incorrect type for 'data', expected table or string, got " .. type(data))
+       end
+
+       local data_length = type(data) == "table" and #data * 4 or string.len(data)
+
+       if data_length ~= expected_byte_count then
+               error(string.format(
+                       "Incorrect length of 'data', width and height imply %d bytes but %d were provided",
+                       expected_byte_count,
+                       data_length
+               ))
+       end
+
+       if type(data) == "table" then
+               local dataBuf = {}
+               for i = 1, #data do
+                       dataBuf[i] = core.colorspec_to_bytes(data[i])
+               end
+               data = table.concat(dataBuf)
+       end
+
+       return o_encode_png(width, height, data, compression or 6)
+end
index 97681655ef48d0728c6120327bdb7210c65070cc..2ff4c093cdcc032badd121b0dfe747f25d8da1e7 100644 (file)
@@ -97,10 +97,6 @@ core.register_privilege("rollback", {
        description = S("Can use the rollback functionality"),
        give_to_singleplayer = false,
 })
-core.register_privilege("basic_debug", {
-       description = S("Can view more debug info that might give a gameplay advantage"),
-       give_to_singleplayer = false,
-})
 core.register_privilege("debug", {
        description = S("Can enable wireframe"),
        give_to_singleplayer = false,
index 56e40c75c9ccf13baf978a6caad240590b1d9bc4..0be107c3633344a378736964522dcf730a213fb1 100644 (file)
@@ -403,8 +403,14 @@ function core.override_item(name, redefinition)
        register_item_raw(item)
 end
 
-
-core.callback_origins = {}
+do
+       local default = {mod = "??", name = "??"}
+       core.callback_origins = setmetatable({}, {
+               __index = function()
+                       return default
+               end
+       })
+end
 
 function core.run_callbacks(callbacks, mode, ...)
        assert(type(callbacks) == "table")
@@ -419,9 +425,7 @@ function core.run_callbacks(callbacks, mode, ...)
        local ret = nil
        for i = 1, cb_len do
                local origin = core.callback_origins[callbacks[i]]
-               if origin then
-                       core.set_last_run_mod(origin.mod)
-               end
+               core.set_last_run_mod(origin.mod)
                local cb_ret = callbacks[i](...)
 
                if mode == 0 and i == 1 then
index db5087a16eede511fc45dee999bfdac936c2c3fd..cb7ff7b7639a0ed168f897e0b441cb007ad3f6dc 100644 (file)
@@ -1,39 +1,39 @@
 -- cache setting
 local enable_damage = core.settings:get_bool("enable_damage")
 
-local health_bar_definition = {
-       hud_elem_type = "statbar",
-       position = {x = 0.5, y = 1},
-       text = "heart.png",
-       text2 = "heart_gone.png",
-       number = core.PLAYER_MAX_HP_DEFAULT,
-       item = core.PLAYER_MAX_HP_DEFAULT,
-       direction = 0,
-       size = {x = 24, y = 24},
-       offset = {x = (-10 * 24) - 25, y = -(48 + 24 + 16)},
-}
-
-local breath_bar_definition = {
-       hud_elem_type = "statbar",
-       position = {x = 0.5, y = 1},
-       text = "bubble.png",
-       text2 = "bubble_gone.png",
-       number = core.PLAYER_MAX_BREATH_DEFAULT,
-       item = core.PLAYER_MAX_BREATH_DEFAULT * 2,
-       direction = 0,
-       size = {x = 24, y = 24},
-       offset = {x = 25, y= -(48 + 24 + 16)},
+local bar_definitions = {
+       hp = {
+               hud_elem_type = "statbar",
+               position = {x = 0.5, y = 1},
+               text = "heart.png",
+               text2 = "heart_gone.png",
+               number = core.PLAYER_MAX_HP_DEFAULT,
+               item = core.PLAYER_MAX_HP_DEFAULT,
+               direction = 0,
+               size = {x = 24, y = 24},
+               offset = {x = (-10 * 24) - 25, y = -(48 + 24 + 16)},
+       },
+       breath = {
+               hud_elem_type = "statbar",
+               position = {x = 0.5, y = 1},
+               text = "bubble.png",
+               text2 = "bubble_gone.png",
+               number = core.PLAYER_MAX_BREATH_DEFAULT * 2,
+               item = core.PLAYER_MAX_BREATH_DEFAULT * 2,
+               direction = 0,
+               size = {x = 24, y = 24},
+               offset = {x = 25, y= -(48 + 24 + 16)},
+       },
 }
 
 local hud_ids = {}
 
-local function scaleToDefault(player, field)
-       -- Scale "hp" or "breath" to the default dimensions
+local function scaleToHudMax(player, field)
+       -- Scale "hp" or "breath" to the hud maximum dimensions
        local current = player["get_" .. field](player)
-       local nominal = core["PLAYER_MAX_" .. field:upper() .. "_DEFAULT"]
-       local max_display = math.max(nominal,
-               math.max(player:get_properties()[field .. "_max"], current))
-       return current / max_display * nominal
+       local nominal = bar_definitions[field].item
+       local max_display = math.max(player:get_properties()[field .. "_max"], current)
+       return math.ceil(current / max_display * nominal)
 end
 
 local function update_builtin_statbars(player)
@@ -55,9 +55,9 @@ local function update_builtin_statbars(player)
        local immortal = player:get_armor_groups().immortal == 1
 
        if flags.healthbar and enable_damage and not immortal then
-               local number = scaleToDefault(player, "hp")
+               local number = scaleToHudMax(player, "hp")
                if hud.id_healthbar == nil then
-                       local hud_def = table.copy(health_bar_definition)
+                       local hud_def = table.copy(bar_definitions.hp)
                        hud_def.number = number
                        hud.id_healthbar = player:hud_add(hud_def)
                else
@@ -73,9 +73,9 @@ local function update_builtin_statbars(player)
        local breath     = player:get_breath()
        local breath_max = player:get_properties().breath_max
        if show_breathbar and breath <= breath_max then
-               local number = 2 * scaleToDefault(player, "breath")
+               local number = scaleToHudMax(player, "breath")
                if not hud.id_breathbar and breath < breath_max then
-                       local hud_def = table.copy(breath_bar_definition)
+                       local hud_def = table.copy(bar_definitions.breath)
                        hud_def.number = number
                        hud.id_breathbar = player:hud_add(hud_def)
                elseif hud.id_breathbar then
@@ -145,7 +145,7 @@ function core.hud_replace_builtin(hud_name, definition)
        end
 
        if hud_name == "health" then
-               health_bar_definition = definition
+               bar_definitions.hp = definition
 
                for name, ids in pairs(hud_ids) do
                        local player = core.get_player_by_name(name)
@@ -159,7 +159,7 @@ function core.hud_replace_builtin(hud_name, definition)
        end
 
        if hud_name == "breath" then
-               breath_bar_definition = definition
+               bar_definitions.breath = definition
 
                for name, ids in pairs(hud_ids) do
                        local player = core.get_player_by_name(name)
index 8bb69a33d26c5b9368c194cca9b2f6bca3b4b3ae..fd176e942dcb3b3e77f849b6c5c68ca16491738e 100644 (file)
@@ -55,8 +55,10 @@ elseif INIT == "mainmenu" then
        if not custom_loaded then
                dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
        end
-elseif INIT == "async" then
-       dofile(asyncpath .. "init.lua")
+elseif INIT == "async"  then
+       dofile(asyncpath .. "mainmenu.lua")
+elseif INIT == "async_game" then
+       dofile(asyncpath .. "game.lua")
 elseif INIT == "client" then
        dofile(clientpath .. "init.lua")
 else
index aa40ffc8d73e98d5004c98e99bab43ba5d2ee1f4..1b29f81e749bd6aa3e5b0edfedea7aab3a2f6ad3 100644 (file)
@@ -139,7 +139,7 @@ This command was disabled by a mod or game.=Dieser Befehl wurde von einer Mod od
 Show or set time of day=Tageszeit anzeigen oder setzen
 Current time is @1:@2.=Es ist jetzt @1:@2 Uhr.
 You don't have permission to run this command (missing privilege: @1).=Sie haben nicht die Erlaubnis, diesen Befehl auszuführen (fehlendes Privileg: @1).
-Invalid time.=Ungültige Zeit.
+Invalid time (must be between 0 and 24000).=Ungültige Zeit (muss zwischen 0 und 24000 liegen).
 Time of day changed.=Tageszeit geändert.
 Invalid hour (must be between 0 and 23 inclusive).=Ungültige Stunde (muss zwischen 0 und 23 inklusive liegen).
 Invalid minute (must be between 0 and 59 inclusive).=Ungültige Minute (muss zwischen 0 und 59 inklusive liegen).
@@ -187,12 +187,14 @@ You are already dead.=Sie sind schon tot.
 @1 is already dead.=@1 ist bereits tot.
 @1 has been killed.=@1 wurde getötet.
 Kill player or yourself=Einen Spieler oder Sie selbst töten
+Invalid parameters (see /help @1).=Ungültige Parameter (siehe „/help @1“).
+Too many arguments, try using just /help <command>=Zu viele Argumente. Probieren Sie es mit „/help <Befehl>“
 Available commands: @1=Verfügbare Befehle: @1
 Use '/help <cmd>' to get more information, or '/help all' to list everything.=„/help <Befehl>“ benutzen, um mehr Informationen zu erhalten, oder „/help all“, um alles aufzulisten.
 Available commands:=Verfügbare Befehle:
 Command not available: @1=Befehl nicht verfügbar: @1
-[all | privs | <cmd>]=[all | privs | <Befehl>]
-Get help for commands or list privileges=Hilfe für Befehle erhalten oder Privilegien auflisten
+[all | privs | <cmd>] [-t]=[all | privs | <Befehl>] [-t]
+Get help for commands or list privileges (-t: output in chat)=Hilfe für Befehle erhalten oder Privilegien auflisten (-t: Ausgabe im Chat)
 Available privileges:=Verfügbare Privilegien:
 Command=Befehl
 Parameters=Parameter
@@ -230,7 +232,8 @@ Can use fly mode=Kann den Flugmodus benutzen
 Can use fast mode=Kann den Schnellmodus benutzen
 Can fly through solid nodes using noclip mode=Kann durch feste Blöcke mit dem Geistmodus fliegen
 Can use the rollback functionality=Kann die Rollback-Funktionalität benutzen
-Allows enabling various debug options that may affect gameplay=Erlaubt die Aktivierung diverser Debugoptionen, die das Spielgeschehen beeinflussen könnten
+Can view more debug info that might give a gameplay advantage=Kann zusätzliche Debuginformationen betrachten, welche einen spielerischen Vorteil geben könnten
+Can enable wireframe=Kann Drahtmodell aktivieren
 Unknown Item=Unbekannter Gegenstand
 Air=Luft
 Ignore=Ignorieren
index 449c2b85e953927f00cf0728f7acbfc2515cf6aa..77f85c766e201bb5c5b80d2cd8a4e493c3aa8235 100644 (file)
@@ -139,7 +139,7 @@ This command was disabled by a mod or game.=Questo comando è stato disabilitato
 Show or set time of day=Mostra o imposta l'orario della giornata
 Current time is @1:@2.=Orario corrente: @1:@2.
 You don't have permission to run this command (missing privilege: @1).=Non hai il permesso di eseguire questo comando (privilegio mancante: @1) 
-Invalid time.=Orario non valido.
+Invalid time (must be between 0 and 24000).=
 Time of day changed.=Orario della giornata cambiato.
 Invalid hour (must be between 0 and 23 inclusive).=Ora non valida (deve essere tra 0 e 23 inclusi)
 Invalid minute (must be between 0 and 59 inclusive).=Minuto non valido (deve essere tra 0 e 59 inclusi)
@@ -187,12 +187,14 @@ You are already dead.=Sei già mortǝ.
 @1 is already dead.=@1 è già mortǝ.
 @1 has been killed.=@1 è stato uccisǝ.
 Kill player or yourself=Uccide un giocatore o te stessǝ
+Invalid parameters (see /help @1).=
+Too many arguments, try using just /help <command>=
 Available commands: @1=Comandi disponibili: @1
 Use '/help <cmd>' to get more information, or '/help all' to list everything.=Usa '/help <comando>' per ottenere più informazioni, o '/help all' per elencare tutti i comandi.
 Available commands:=Comandi disponibili:
 Command not available: @1=Comando non disponibile: @1
-[all | privs | <cmd>]=[all | privs | <comando>]
-Get help for commands or list privileges=Richiama la finestra d'aiuto dei comandi o dei privilegi
+[all | privs | <cmd>] [-t]=
+Get help for commands or list privileges (-t: output in chat)=
 Available privileges:=Privilegi disponibili:
 Command=Comando
 Parameters=Parametri
@@ -230,7 +232,8 @@ Can use fly mode=Si può usare la modalità volo
 Can use fast mode=Si può usare la modalità rapida
 Can fly through solid nodes using noclip mode=Si può volare attraverso i nodi solidi con la modalità incorporea
 Can use the rollback functionality=Si può usare la funzione di rollback
-Allows enabling various debug options that may affect gameplay=Permette di abilitare varie opzioni di debug che potrebbero influenzare l'esperienza di gioco
+Can view more debug info that might give a gameplay advantage=
+Can enable wireframe=
 Unknown Item=Oggetto sconosciuto
 Air=Aria
 Ignore=Ignora
@@ -244,6 +247,10 @@ Profile saved to @1=
 
 ##### not used anymore #####
 
+Invalid time.=Orario non valido.
+[all | privs | <cmd>]=[all | privs | <comando>]
+Get help for commands or list privileges=Richiama la finestra d'aiuto dei comandi o dei privilegi
+Allows enabling various debug options that may affect gameplay=Permette di abilitare varie opzioni di debug che potrebbero influenzare l'esperienza di gioco
 [<delay_in_seconds> | -1] [reconnect] [<message>]=[<ritardo_in_secondi> | -1] [reconnect] [<messaggio>]
 Shutdown server (-1 cancels a delayed shutdown)=Arresta il server (-1 annulla un arresto programmato)
 <name> (<privilege> | all)=<nome> (<privilegio> | all)
index 7049dde3664f1e7f0c6d5b9eefa2485391bf1a89..308d17f37300d2eda3c18d78e0b83c9917e8e58c 100644 (file)
@@ -139,7 +139,7 @@ This command was disabled by a mod or game.=
 Show or set time of day=
 Current time is @1:@2.=
 You don't have permission to run this command (missing privilege: @1).=
-Invalid time.=
+Invalid time (must be between 0 and 24000).=
 Time of day changed.=
 Invalid hour (must be between 0 and 23 inclusive).=
 Invalid minute (must be between 0 and 59 inclusive).=
@@ -187,12 +187,14 @@ You are already dead.=
 @1 is already dead.=
 @1 has been killed.=
 Kill player or yourself=
+Invalid parameters (see /help @1).=
+Too many arguments, try using just /help <command>=
 Available commands: @1=
 Use '/help <cmd>' to get more information, or '/help all' to list everything.=
 Available commands:=
 Command not available: @1=
-[all | privs | <cmd>]=
-Get help for commands or list privileges=
+[all | privs | <cmd>] [-t]=
+Get help for commands or list privileges (-t: output in chat)=
 Available privileges:=
 Command=
 Parameters=
@@ -230,7 +232,8 @@ Can use fly mode=
 Can use fast mode=
 Can fly through solid nodes using noclip mode=
 Can use the rollback functionality=
-Allows enabling various debug options that may affect gameplay=
+Can view more debug info that might give a gameplay advantage=
+Can enable wireframe=
 Unknown Item=
 Air=
 Ignore=
index 6db3510481e1701c89d2090f8de2f7643513cdc1..8db8bb8d17f19c0515d980c71da83c1efc2b7c87 100644 (file)
@@ -119,31 +119,27 @@ function render_serverlist_row(spec)
 
        return table.concat(details, ",")
 end
-
---------------------------------------------------------------------------------
-os.tempfolder = function()
-       local temp = core.get_temp_path()
-       return temp .. DIR_DELIM .. "MT_" .. math.random(0, 10000)
-end
-
+---------------------------------------------------------------------------------
 os.tmpname = function()
-       local path = os.tempfolder()
-       io.open(path, "w"):close()
-       return path
+       error('do not use') -- instead use core.get_temp_path()
 end
 --------------------------------------------------------------------------------
 
-function menu_render_worldlist()
-       local retval = ""
+function menu_render_worldlist(show_gameid)
+       local retval = {}
        local current_worldlist = menudata.worldlist:get_list()
 
+       local row
        for i, v in ipairs(current_worldlist) do
-               if retval ~= "" then retval = retval .. "," end
-               retval = retval .. core.formspec_escape(v.name) ..
-                               " \\[" .. core.formspec_escape(v.gameid) .. "\\]"
+               row = v.name
+               if show_gameid == nil or show_gameid == true then
+                       row = row .. " [" .. v.gameid .. "]"
+               end
+               retval[#retval+1] = core.formspec_escape(row)
+
        end
 
-       return retval
+       return table.concat(retval, ",")
 end
 
 function menu_handle_key_up_down(fields, textlist, settingname)
index 9bdf92a74fec2977e94067949d158816a6e4b459..f73256612068e70ed6ff9e1cbbe5c10187873b5d 100644 (file)
@@ -163,10 +163,13 @@ local function get_formspec(data)
                        "button[8.95,0.125;2.5,0.5;btn_enable_all_mods;" ..
                        fgettext("Enable all") .. "]"
        end
+
+       local use_technical_names = core.settings:get_bool("show_technical_names")
+
        return retval ..
                "tablecolumns[color;tree;text]" ..
                "table[5.5,0.75;5.75,6;world_config_modlist;" ..
-               pkgmgr.render_packagelist(data.list) .. ";" .. data.selected_mod .."]"
+               pkgmgr.render_packagelist(data.list, use_technical_names) .. ";" .. data.selected_mod .."]"
 end
 
 local function handle_buttons(this, fields)
@@ -205,14 +208,19 @@ local function handle_buttons(this, fields)
                local mods = worldfile:to_table()
 
                local rawlist = this.data.list:get_raw_list()
+               local was_set = {}
 
                for i = 1, #rawlist do
                        local mod = rawlist[i]
                        if not mod.is_modpack and
                                        not mod.is_game_content then
                                if modname_valid(mod.name) then
-                                       worldfile:set("load_mod_" .. mod.name,
-                                               mod.enabled and "true" or "false")
+                                       if mod.enabled then
+                                               worldfile:set("load_mod_" .. mod.name, mod.virtual_path)
+                                               was_set[mod.name] = true
+                                       elseif not was_set[mod.name] then
+                                               worldfile:set("load_mod_" .. mod.name, "false")
+                                       end
                                elseif mod.enabled then
                                        gamedata.errormessage = fgettext_ne("Failed to enable mo" ..
                                                        "d \"$1\" as it contains disallowed characters. " ..
@@ -256,12 +264,26 @@ local function handle_buttons(this, fields)
        if fields.btn_enable_all_mods then
                local list = this.data.list:get_raw_list()
 
+               -- When multiple copies of a mod are installed, we need to avoid enabling multiple of them
+               -- at a time. So lets first collect all the enabled mods, and then use this to exclude
+               -- multiple enables.
+
+               local was_enabled = {}
                for i = 1, #list do
                        if not list[i].is_game_content
-                                       and not list[i].is_modpack then
+                                       and not list[i].is_modpack and list[i].enabled then
+                               was_enabled[list[i].name] = true
+                       end
+               end
+
+               for i = 1, #list do
+                       if not list[i].is_game_content and not list[i].is_modpack and
+                                       not was_enabled[list[i].name] then
                                list[i].enabled = true
+                               was_enabled[list[i].name] = true
                        end
                end
+
                enabled_all = true
                return true
        end
index 790da03bafc3fdcc01c9a4ae6378b6030b585147..ff32c8c9f7d0d689071ffa375eb32b9f14f37fe7 100644 (file)
@@ -25,7 +25,7 @@ end
 
 -- Unordered preserves the original order of the ContentDB API,
 -- before the package list is ordered based on installed state.
-local store = { packages = {}, packages_full = {}, packages_full_unordered = {} }
+local store = { packages = {}, packages_full = {}, packages_full_unordered = {}, aliases = {} }
 
 local http = core.get_http_api()
 
@@ -62,9 +62,19 @@ local REASON_UPDATE = "update"
 local REASON_DEPENDENCY = "dependency"
 
 
+-- encodes for use as URL parameter or path component
+local function urlencode(str)
+       return str:gsub("[^%a%d()._~-]", function(char)
+               return string.format("%%%02X", string.byte(char))
+       end)
+end
+assert(urlencode("sample text?") == "sample%20text%3F")
+
+
 local function get_download_url(package, reason)
        local base_url = core.settings:get("contentdb_url")
-       local ret = base_url .. ("/packages/%s/%s/releases/%d/download/"):format(package.author, package.name, package.release)
+       local ret = base_url .. ("/packages/%s/releases/%d/download/"):format(
+               package.url_part, package.release)
        if reason then
                ret = ret .. "?reason=" .. reason
        end
@@ -72,34 +82,52 @@ local function get_download_url(package, reason)
 end
 
 
-local function download_package(param)
-       if core.download_file(param.url, param.filename) then
+local function download_and_extract(param)
+       local package = param.package
+
+       local filename = core.get_temp_path(true)
+       if filename == "" or not core.download_file(param.url, filename) then
+               core.log("error", "Downloading " .. dump(param.url) .. " failed")
                return {
-                       filename = param.filename,
-                       successful = true,
+                       msg = fgettext("Failed to download $1", package.name)
                }
+       end
+
+       local tempfolder = core.get_temp_path()
+       if tempfolder ~= "" then
+               tempfolder = tempfolder .. DIR_DELIM .. "MT_" .. math.random(1, 1024000)
+               if not core.extract_zip(filename, tempfolder) then
+                       tempfolder = nil
+               end
        else
-               core.log("error", "downloading " .. dump(param.url) .. " failed")
+               tempfolder = nil
+       end
+       os.remove(filename)
+       if not tempfolder then
                return {
-                       successful = false,
+                       msg = fgettext("Install: Unsupported file type or broken archive"),
                }
        end
+
+       return {
+               path = tempfolder
+       }
 end
 
 local function start_install(package, reason)
        local params = {
                package = package,
                url = get_download_url(package, reason),
-               filename = os.tempfolder() .. "_MODNAME_" .. package.name .. ".zip",
        }
 
        number_downloading = number_downloading + 1
 
        local function callback(result)
-               if result.successful then
-                       local path, msg = pkgmgr.install(package.type,
-                                       result.filename, package.name,
-                                       package.path)
+               if result.msg then
+                       gamedata.errormessage = result.msg
+               else
+                       local path, msg = pkgmgr.install_dir(package.type, result.path, package.name, package.path)
+                       core.delete_dir(result.path)
                        if not path then
                                gamedata.errormessage = msg
                        else
@@ -137,9 +165,6 @@ local function start_install(package, reason)
                                        conf:write()
                                end
                        end
-                       os.remove(result.filename)
-               else
-                       gamedata.errormessage = fgettext("Failed to download $1", package.name)
                end
 
                package.downloading = false
@@ -159,7 +184,7 @@ local function start_install(package, reason)
        package.queued = false
        package.downloading = true
 
-       if not core.handle_async(download_package, params, callback) then
+       if not core.handle_async(download_and_extract, params, callback) then
                core.log("error", "ERROR: async event failed")
                gamedata.errormessage = fgettext("Failed to download $1", package.name)
                return
@@ -184,7 +209,7 @@ local function get_raw_dependencies(package)
        local url_fmt = "/api/packages/%s/dependencies/?only_hard=1&protocol_version=%s&engine_version=%s"
        local version = core.get_version()
        local base_url = core.settings:get("contentdb_url")
-       local url = base_url .. url_fmt:format(package.id, core.get_max_supp_proto(), version.string)
+       local url = base_url .. url_fmt:format(package.url_part, core.get_max_supp_proto(), urlencode(version.string))
 
        local response = http.fetch_sync({ url = url })
        if not response.succeeded then
@@ -559,17 +584,16 @@ function store.load()
        local base_url = core.settings:get("contentdb_url")
        local url = base_url ..
                "/api/packages/?type=mod&type=game&type=txp&protocol_version=" ..
-               core.get_max_supp_proto() .. "&engine_version=" .. version.string
+               core.get_max_supp_proto() .. "&engine_version=" .. urlencode(version.string)
 
        for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do
                item = item:trim()
                if item ~= "" then
-                       url = url .. "&hide=" .. item
+                       url = url .. "&hide=" .. urlencode(item)
                end
        end
 
-       local timeout = tonumber(core.settings:get("curl_file_download_timeout"))
-       local response = http.fetch_sync({ url = url, timeout = timeout })
+       local response = http.fetch_sync({ url = url })
        if not response.succeeded then
                return
        end
@@ -579,12 +603,16 @@ function store.load()
 
        for _, package in pairs(store.packages_full) do
                local name_len = #package.name
+               -- This must match what store.update_paths() does!
+               package.id = package.author:lower() .. "/"
                if package.type == "game" and name_len > 5 and package.name:sub(name_len - 4) == "_game" then
-                       package.id = package.author:lower() .. "/" .. package.name:sub(1, name_len - 5)
+                       package.id = package.id .. package.name:sub(1, name_len - 5)
                else
-                       package.id = package.author:lower() .. "/" .. package.name
+                       package.id = package.id .. package.name
                end
 
+               package.url_part = urlencode(package.author) .. "/" .. urlencode(package.name)
+
                if package.aliases then
                        for _, alias in ipairs(package.aliases) do
                                -- We currently don't support name changing
@@ -834,8 +862,7 @@ function store.get_formspec(dlgdata)
                        formspec[#formspec + 1] = "cdb_downloading.png;3;400;]"
                elseif package.queued then
                        formspec[#formspec + 1] = left_base
-                       formspec[#formspec + 1] = core.formspec_escape(defaulttexturedir)
-                       formspec[#formspec + 1] = "cdb_queued.png;queued]"
+                       formspec[#formspec + 1] = "cdb_queued.png;queued;]"
                elseif not package.path then
                        local elem_name = "install_" .. i .. ";"
                        formspec[#formspec + 1] = "style[" .. elem_name .. "bgcolor=#71aa34]"
@@ -998,9 +1025,9 @@ function store.handle_submit(this, fields)
                end
 
                if fields["view_" .. i] then
-                       local url = ("%s/packages/%s/%s?protocol_version=%d"):format(
-                                       core.settings:get("contentdb_url"),
-                                       package.author, package.name, core.get_max_supp_proto())
+                       local url = ("%s/packages/%s?protocol_version=%d"):format(
+                                       core.settings:get("contentdb_url"), package.url_part,
+                                       core.get_max_supp_proto())
                        core.open_url(url)
                        return true
                end
index 1938747fe13f32db4ec5fd2cee4dd4dd6b89c9ac..76ceb0f16c7d0325d1dd81c6671d6016c002fdbd 100644 (file)
@@ -15,7 +15,8 @@
 --with this program; if not, write to the Free Software Foundation, Inc.,
 --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-local worldname = ""
+-- cf. tab_local, the gamebar already provides game selection so we hide the list from here
+local hide_gamelist = PLATFORM ~= "Android"
 
 local function table_to_flags(ftable)
        -- Convert e.g. { jungles = true, caves = false } to "jungles,nocaves"
@@ -31,9 +32,8 @@ local function strflag(flags, flag)
        return (flags[flag] == true) and "true" or "false"
 end
 
-local cb_caverns = { "caverns", fgettext("Caverns"), "caverns",
+local cb_caverns = { "caverns", fgettext("Caverns"),
        fgettext("Very large caverns deep in the underground") }
-local tt_sea_rivers = fgettext("Sea level rivers")
 
 local flag_checkboxes = {
        v5 = {
@@ -41,39 +41,38 @@ local flag_checkboxes = {
        },
        v7 = {
                cb_caverns,
-               { "ridges", fgettext("Rivers"), "ridges", tt_sea_rivers },
-               { "mountains", fgettext("Mountains"), "mountains" },
-               { "floatlands", fgettext("Floatlands (experimental)"), "floatlands",
+               { "ridges", fgettext("Rivers"), fgettext("Sea level rivers") },
+               { "mountains", fgettext("Mountains") },
+               { "floatlands", fgettext("Floatlands (experimental)"),
                fgettext("Floating landmasses in the sky") },
        },
        carpathian = {
                cb_caverns,
-               { "rivers", fgettext("Rivers"), "rivers", tt_sea_rivers },
+               { "rivers", fgettext("Rivers"), fgettext("Sea level rivers") },
        },
        valleys = {
-               { "altitude-chill", fgettext("Altitude chill"), "altitude_chill",
+               { "altitude_chill", fgettext("Altitude chill"),
                fgettext("Reduces heat with altitude") },
-               { "altitude-dry", fgettext("Altitude dry"), "altitude_dry",
+               { "altitude_dry", fgettext("Altitude dry"),
                fgettext("Reduces humidity with altitude") },
-               { "humid-rivers", fgettext("Humid rivers"), "humid_rivers",
+               { "humid_rivers", fgettext("Humid rivers"),
                fgettext("Increases humidity around rivers") },
-               { "vary-river-depth", fgettext("Vary river depth"), "vary_river_depth",
+               { "vary_river_depth", fgettext("Vary river depth"),
                fgettext("Low humidity and high heat causes shallow or dry rivers") },
        },
        flat = {
                cb_caverns,
-               { "hills", fgettext("Hills"), "hills" },
-               { "lakes", fgettext("Lakes"), "lakes" },
+               { "hills", fgettext("Hills") },
+               { "lakes", fgettext("Lakes") },
        },
        fractal = {
-               { "terrain", fgettext("Additional terrain"), "terrain",
+               { "terrain", fgettext("Additional terrain"),
                fgettext("Generate non-fractal terrain: Oceans and underground") },
        },
        v6 = {
-               { "trees", fgettext("Trees and jungle grass"), "trees" },
-               { "flat", fgettext("Flat terrain"), "flat" },
-               { "mudflow", fgettext("Mud flow"), "mudflow",
-               fgettext("Terrain surface erosion") },
+               { "trees", fgettext("Trees and jungle grass") },
+               { "flat", fgettext("Flat terrain") },
+               { "mudflow", fgettext("Mud flow"), fgettext("Terrain surface erosion") },
                -- Biome settings are in mgv6_biomes below
        },
 }
@@ -105,38 +104,26 @@ local function create_world_formspec(dialogdata)
                        "button[4.75,2.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
        end
 
+       local current_mg = dialogdata.mg
        local mapgens = core.get_mapgen_names()
 
-       local current_seed = core.settings:get("fixed_map_seed") or ""
-       local current_mg   = core.settings:get("mg_name")
        local gameid = core.settings:get("menu_last_game")
 
-       local flags = {
-               main = core.settings:get_flags("mg_flags"),
-               v5 = core.settings:get_flags("mgv5_spflags"),
-               v6 = core.settings:get_flags("mgv6_spflags"),
-               v7 = core.settings:get_flags("mgv7_spflags"),
-               fractal = core.settings:get_flags("mgfractal_spflags"),
-               carpathian = core.settings:get_flags("mgcarpathian_spflags"),
-               valleys = core.settings:get_flags("mgvalleys_spflags"),
-               flat = core.settings:get_flags("mgflat_spflags"),
-       }
-
-       local gameidx = 0
-       if gameid ~= nil then
-               local _
-               _, gameidx = pkgmgr.find_by_gameid(gameid)
+       local flags = dialogdata.flags
 
-               if gameidx == nil then
-                       gameidx = 0
-               end
+       local game, gameidx = pkgmgr.find_by_gameid(gameid)
+       if game == nil and hide_gamelist then
+               -- should never happen but just pick the first game
+               game = pkgmgr.get_game(1)
+               gameidx = 1
+               core.settings:set("menu_last_game", game.id)
+       elseif game == nil then
+               gameidx = 0
        end
 
-       local game_by_gameidx = core.get_game(gameidx)
        local disallowed_mapgen_settings = {}
-       if game_by_gameidx ~= nil then
-               local gamepath = game_by_gameidx.path
-               local gameconfig = Settings(gamepath.."/game.conf")
+       if game ~= nil then
+               local gameconfig = Settings(game.path.."/game.conf")
 
                local allowed_mapgens = (gameconfig:get("allowed_mapgens") or ""):split()
                for key, value in pairs(allowed_mapgens) do
@@ -156,7 +143,7 @@ local function create_world_formspec(dialogdata)
                        end
                end
 
-               if disallowed_mapgens then
+               if #disallowed_mapgens > 0 then
                        for i = #mapgens, 1, -1 do
                                if table.indexof(disallowed_mapgens, mapgens[i]) > 0 then
                                        table.remove(mapgens, i)
@@ -172,23 +159,29 @@ local function create_world_formspec(dialogdata)
 
        local mglist = ""
        local selindex
-       local i = 1
-       local first_mg
-       for k,v in pairs(mapgens) do
-               if not first_mg then
-                       first_mg = v
+       do -- build the list of mapgens
+               local i = 1
+               local first_mg
+               for k, v in pairs(mapgens) do
+                       if not first_mg then
+                               first_mg = v
+                       end
+                       if current_mg == v then
+                               selindex = i
+                       end
+                       i = i + 1
+                       mglist = mglist .. core.formspec_escape(v) .. ","
                end
-               if current_mg == v then
-                       selindex = i
+               if not selindex then
+                       selindex = 1
+                       current_mg = first_mg
                end
-               i = i + 1
-               mglist = mglist .. v .. ","
-       end
-       if not selindex then
-               selindex = 1
-               current_mg = first_mg
+               mglist = mglist:sub(1, -2)
        end
-       mglist = mglist:sub(1, -2)
+
+       -- The logic of the flag element IDs is as follows:
+       -- "flag_main_foo-bar-baz" controls dialogdata.flags["main"]["foo_bar_baz"]
+       -- see the buttonhandler for the implementation of this
 
        local mg_main_flags = function(mapgen, y)
                if mapgen == "singlenode" then
@@ -198,11 +191,11 @@ local function create_world_formspec(dialogdata)
                        return "", y
                end
 
-               local form = "checkbox[0," .. y .. ";flag_mg_caves;" ..
+               local form = "checkbox[0," .. y .. ";flag_main_caves;" ..
                        fgettext("Caves") .. ";"..strflag(flags.main, "caves").."]"
                y = y + 0.5
 
-               form = form .. "checkbox[0,"..y..";flag_mg_dungeons;" ..
+               form = form .. "checkbox[0,"..y..";flag_main_dungeons;" ..
                        fgettext("Dungeons") .. ";"..strflag(flags.main, "dungeons").."]"
                y = y + 0.5
 
@@ -213,7 +206,7 @@ local function create_world_formspec(dialogdata)
                else
                        d_tt = fgettext("Structures appearing on the terrain, typically trees and plants")
                end
-               form = form .. "checkbox[0,"..y..";flag_mg_decorations;" ..
+               form = form .. "checkbox[0,"..y..";flag_main_decorations;" ..
                        d_name .. ";" ..
                        strflag(flags.main, "decorations").."]" ..
                        "tooltip[flag_mg_decorations;" ..
@@ -221,7 +214,7 @@ local function create_world_formspec(dialogdata)
                        "]"
                y = y + 0.5
 
-               form = form .. "tooltip[flag_mg_caves;" ..
+               form = form .. "tooltip[flag_main_caves;" ..
                fgettext("Network of tunnels and caves")
                .. "]"
                return form, y
@@ -235,13 +228,13 @@ local function create_world_formspec(dialogdata)
                        return "", y
                end
                local form = ""
-               for _,tab in pairs(flag_checkboxes[mapgen]) do
-                       local id = "flag_mg"..mapgen.."_"..tab[1]
+               for _, tab in pairs(flag_checkboxes[mapgen]) do
+                       local id = "flag_"..mapgen.."_"..tab[1]:gsub("_", "-")
                        form = form .. ("checkbox[0,%f;%s;%s;%s]"):
-                               format(y, id, tab[2], strflag(flags[mapgen], tab[3]))
+                               format(y, id, tab[2], strflag(flags[mapgen], tab[1]))
 
-                       if tab[4] then
-                               form = form .. "tooltip["..id..";"..tab[4].."]"
+                       if tab[3] then
+                               form = form .. "tooltip["..id..";"..tab[3].."]"
                        end
                        y = y + 0.5
                end
@@ -277,16 +270,14 @@ local function create_world_formspec(dialogdata)
 
                -- biomeblend
                y = y + 0.55
-               form = form .. "checkbox[0,"..y..";flag_mgv6_biomeblend;" ..
+               form = form .. "checkbox[0,"..y..";flag_v6_biomeblend;" ..
                        fgettext("Biome blending") .. ";"..strflag(flags.v6, "biomeblend").."]" ..
-                       "tooltip[flag_mgv6_biomeblend;" ..
+                       "tooltip[flag_v6_biomeblend;" ..
                        fgettext("Smooth transition between biomes") .. "]"
 
                return form, y
        end
 
-       current_seed = core.formspec_escape(current_seed)
-
        local y_start = 0.0
        local y = y_start
        local str_flags, str_spflags
@@ -323,21 +314,32 @@ local function create_world_formspec(dialogdata)
                "container[0,0]"..
                "field[0.3,0.6;6,0.5;te_world_name;" ..
                fgettext("World name") ..
-               ";" .. core.formspec_escape(worldname) .. "]" ..
+               ";" .. core.formspec_escape(dialogdata.worldname) .. "]" ..
+               "set_focus[te_world_name;false]"
+
+       if not disallowed_mapgen_settings["seed"] then
 
-               "field[0.3,1.7;6,0.5;te_seed;" ..
-               fgettext("Seed") ..
-               ";".. current_seed .. "]" ..
+               retval = retval .. "field[0.3,1.7;6,0.5;te_seed;" ..
+                               fgettext("Seed") ..
+                               ";".. core.formspec_escape(dialogdata.seed) .. "]"
+
+       end
 
+       retval = retval ..
                "label[0,2;" .. fgettext("Mapgen") .. "]"..
-               "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
+               "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]"
+
+       if not hide_gamelist or devtest_only ~= "" then
+               retval = retval ..
+                       "label[0,3.35;" .. fgettext("Game") .. "]"..
+                       "textlist[0,3.85;5.8,"..gamelist_height..";games;" ..
+                       pkgmgr.gamelist() .. ";" .. gameidx .. ";false]" ..
+                       "container[0,4.5]" ..
+                       devtest_only ..
+                       "container_end[]"
+       end
 
-               "label[0,3.35;" .. fgettext("Game") .. "]"..
-               "textlist[0,3.85;5.8,"..gamelist_height..";games;" ..
-               pkgmgr.gamelist() .. ";" .. gameidx .. ";false]" ..
-               "container[0,4.5]" ..
-               devtest_only ..
-               "container_end[]" ..
+       retval = retval ..
                "container_end[]" ..
 
                -- Right side
@@ -360,9 +362,20 @@ local function create_world_buttonhandler(this, fields)
                fields["key_enter"] then
 
                local worldname = fields["te_world_name"]
-               local gameindex = core.get_textlist_index("games")
+               local game, gameindex
+               if hide_gamelist then
+                       game, gameindex = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
+               else
+                       gameindex = core.get_textlist_index("games")
+                       game = pkgmgr.get_game(gameindex)
+               end
+
+               local message
+               if game == nil then
+                       message = fgettext("No game selected")
+               end
 
-               if gameindex ~= nil then
+               if message == nil then
                        -- For unnamed worlds use the generated name 'world<number>',
                        -- where the number increments: it is set to 1 larger than the largest
                        -- generated name number found.
@@ -377,36 +390,48 @@ local function create_world_buttonhandler(this, fields)
                                worldname = "world" .. worldnum_max + 1
                        end
 
-                       core.settings:set("fixed_map_seed", fields["te_seed"])
-
-                       local message
-                       if not menudata.worldlist:uid_exists_raw(worldname) then
-                               core.settings:set("mg_name",fields["dd_mapgen"])
-                               message = core.create_world(worldname,gameindex)
-                       else
+                       if menudata.worldlist:uid_exists_raw(worldname) then
                                message = fgettext("A world named \"$1\" already exists", worldname)
                        end
+               end
 
-                       if message ~= nil then
-                               gamedata.errormessage = message
-                       else
-                               core.settings:set("menu_last_game",pkgmgr.games[gameindex].id)
-                               if this.data.update_worldlist_filter then
-                                       menudata.worldlist:set_filtercriteria(pkgmgr.games[gameindex].id)
-                                       mm_texture.update("singleplayer", pkgmgr.games[gameindex].id)
-                               end
-                               menudata.worldlist:refresh()
-                               core.settings:set("mainmenu_last_selected_world",
-                                                                       menudata.worldlist:raw_index_by_uid(worldname))
+               if message == nil then
+                       this.data.seed = fields["te_seed"] or ""
+                       this.data.mg = fields["dd_mapgen"]
+
+                       -- actual names as used by engine
+                       local settings = {
+                               fixed_map_seed = this.data.seed,
+                               mg_name = this.data.mg,
+                               mg_flags = table_to_flags(this.data.flags.main),
+                               mgv5_spflags = table_to_flags(this.data.flags.v5),
+                               mgv6_spflags = table_to_flags(this.data.flags.v6),
+                               mgv7_spflags = table_to_flags(this.data.flags.v7),
+                               mgfractal_spflags = table_to_flags(this.data.flags.fractal),
+                               mgcarpathian_spflags = table_to_flags(this.data.flags.carpathian),
+                               mgvalleys_spflags = table_to_flags(this.data.flags.valleys),
+                               mgflat_spflags = table_to_flags(this.data.flags.flat),
+                       }
+                       message = core.create_world(worldname, gameindex, settings)
+               end
+
+               if message == nil then
+                       core.settings:set("menu_last_game", game.id)
+                       if this.data.update_worldlist_filter then
+                               menudata.worldlist:set_filtercriteria(game.id)
                        end
-               else
-                       gamedata.errormessage = fgettext("No game selected")
+                       menudata.worldlist:refresh()
+                       core.settings:set("mainmenu_last_selected_world",
+                                       menudata.worldlist:raw_index_by_uid(worldname))
                end
+
+               gamedata.errormessage = message
                this:delete()
                return true
        end
 
-       worldname = fields.te_world_name
+       this.data.worldname = fields["te_world_name"]
+       this.data.seed = fields["te_seed"] or ""
 
        if fields["games"] then
                local gameindex = core.get_textlist_index("games")
@@ -417,22 +442,11 @@ local function create_world_buttonhandler(this, fields)
        for k,v in pairs(fields) do
                local split = string.split(k, "_", nil, 3)
                if split and split[1] == "flag" then
-                       local setting
-                       if split[2] == "mg" then
-                               setting = "mg_flags"
-                       else
-                               setting = split[2].."_spflags"
-                       end
                        -- We replaced the underscore of flag names with a dash.
                        local flag = string.gsub(split[3], "-", "_")
-                       local ftable = core.settings:get_flags(setting)
-                       if v == "true" then
-                               ftable[flag] = true
-                       else
-                               ftable[flag] = false
-                       end
-                       local flags = table_to_flags(ftable)
-                       core.settings:set(setting, flags)
+                       local ftable = this.data.flags[split[2]]
+                       assert(ftable)
+                       ftable[flag] = v == "true"
                        return true
                end
        end
@@ -446,18 +460,16 @@ local function create_world_buttonhandler(this, fields)
                local entry = core.formspec_escape(fields["mgv6_biomes"])
                for b=1, #mgv6_biomes do
                        if entry == mgv6_biomes[b][1] then
-                               local ftable = core.settings:get_flags("mgv6_spflags")
+                               local ftable = this.data.flags.v6
                                ftable.jungles = mgv6_biomes[b][2].jungles
                                ftable.snowbiomes = mgv6_biomes[b][2].snowbiomes
-                               local flags = table_to_flags(ftable)
-                               core.settings:set("mgv6_spflags", flags)
                                return true
                        end
                end
        end
 
        if fields["dd_mapgen"] then
-               core.settings:set("mg_name", fields["dd_mapgen"])
+               this.data.mg = fields["dd_mapgen"]
                return true
        end
 
@@ -466,12 +478,27 @@ end
 
 
 function create_create_world_dlg(update_worldlistfilter)
-       worldname = ""
        local retval = dialog_create("sp_create_world",
                                        create_world_formspec,
                                        create_world_buttonhandler,
                                        nil)
-       retval.update_worldlist_filter = update_worldlistfilter
+       retval.data = {
+               update_worldlist_filter = update_worldlistfilter,
+               worldname = "",
+               -- settings the world is created with:
+               seed = core.settings:get("fixed_map_seed") or "",
+               mg = core.settings:get("mg_name"),
+               flags = {
+                       main = core.settings:get_flags("mg_flags"),
+                       v5 = core.settings:get_flags("mgv5_spflags"),
+                       v6 = core.settings:get_flags("mgv6_spflags"),
+                       v7 = core.settings:get_flags("mgv7_spflags"),
+                       fractal = core.settings:get_flags("mgfractal_spflags"),
+                       carpathian = core.settings:get_flags("mgcarpathian_spflags"),
+                       valleys = core.settings:get_flags("mgvalleys_spflags"),
+                       flat = core.settings:get_flags("mgflat_spflags"),
+               }
+       }
 
        return retval
 end
index 38a658969955bcbcae9c50e37bda19db83ebcfe4..d6f485cf73d29c2176b1c16a51bf8b2e94e9b2d4 100644 (file)
@@ -378,7 +378,7 @@ local function parse_config_file(read_all, parse_mods)
                -- Parse mods
                local mods_category_initialized = false
                local mods = {}
-               get_mods(core.get_modpath(), mods)
+               get_mods(core.get_modpath(), "mods", mods)
                for _, mod in ipairs(mods) do
                        local path = mod.path .. DIR_DELIM .. FILENAME
                        local file = io.open(path, "r")
@@ -395,6 +395,7 @@ local function parse_config_file(read_all, parse_mods)
 
                                table.insert(settings, {
                                        name = mod.name,
+                                       readable_name = mod.title,
                                        level = 1,
                                        type = "category",
                                })
@@ -408,7 +409,7 @@ local function parse_config_file(read_all, parse_mods)
                -- Parse clientmods
                local clientmods_category_initialized = false
                local clientmods = {}
-               get_mods(core.get_clientmodpath(), clientmods)
+               get_mods(core.get_clientmodpath(), "clientmods", clientmods)
                for _, clientmod in ipairs(clientmods) do
                        local path = clientmod.path .. DIR_DELIM .. FILENAME
                        local file = io.open(path, "r")
@@ -527,44 +528,40 @@ end
 
 local function get_current_np_group(setting)
        local value = core.settings:get_np_group(setting.name)
-       local t = {}
        if value == nil then
-               t = setting.values
-       else
-               table.insert(t, value.offset)
-               table.insert(t, value.scale)
-               table.insert(t, value.spread.x)
-               table.insert(t, value.spread.y)
-               table.insert(t, value.spread.z)
-               table.insert(t, value.seed)
-               table.insert(t, value.octaves)
-               table.insert(t, value.persistence)
-               table.insert(t, value.lacunarity)
-               table.insert(t, value.flags)
+               return setting.values
        end
-       return t
+       local p = "%g"
+       return {
+               p:format(value.offset),
+               p:format(value.scale),
+               p:format(value.spread.x),
+               p:format(value.spread.y),
+               p:format(value.spread.z),
+               p:format(value.seed),
+               p:format(value.octaves),
+               p:format(value.persistence),
+               p:format(value.lacunarity),
+               value.flags
+       }
 end
 
 local function get_current_np_group_as_string(setting)
        local value = core.settings:get_np_group(setting.name)
-       local t
        if value == nil then
-               t = setting.default
-       else
-               t = value.offset .. ", " ..
-                       value.scale .. ", (" ..
-                       value.spread.x .. ", " ..
-                       value.spread.y .. ", " ..
-                       value.spread.z .. "), " ..
-                       value.seed .. ", " ..
-                       value.octaves .. ", " ..
-                       value.persistence .. ", " ..
-                       value.lacunarity
-               if value.flags ~= "" then
-                       t = t .. ", " .. value.flags
-               end
+               return setting.default
        end
-       return t
+       return ("%g, %g, (%g, %g, %g), %g, %g, %g, %g"):format(
+               value.offset,
+               value.scale,
+               value.spread.x,
+               value.spread.y,
+               value.spread.z,
+               value.seed,
+               value.octaves,
+               value.persistence,
+               value.lacunarity
+       ) .. (value.flags ~= "" and (", " .. value.flags) or "")
 end
 
 local checkboxes = {} -- handle checkboxes events
@@ -697,7 +694,7 @@ local function create_change_setting_formspec(dialogdata)
        elseif setting.type == "v3f" then
                local val = get_current_value(setting)
                local v3f = {}
-               for line in val:gmatch("[+-]?[%d.-e]+") do -- All numeric characters
+               for line in val:gmatch("[+-]?[%d.+-eE]+") do -- All numeric characters
                        table.insert(v3f, line)
                end
 
@@ -990,7 +987,7 @@ local function create_settings_formspec(tabview, _, tabdata)
        local current_level = 0
        for _, entry in ipairs(settings) do
                local name
-               if not core.settings:get_bool("main_menu_technical_settings") and entry.readable_name then
+               if not core.settings:get_bool("show_technical_names") and entry.readable_name then
                        name = fgettext_ne(entry.readable_name)
                else
                        name = entry.name
@@ -1031,7 +1028,7 @@ local function create_settings_formspec(tabview, _, tabdata)
                        "button[10,4.9;2,1;btn_edit;" .. fgettext("Edit") .. "]" ..
                        "button[7,4.9;3,1;btn_restore;" .. fgettext("Restore Default") .. "]" ..
                        "checkbox[0,4.3;cb_tech_settings;" .. fgettext("Show technical names") .. ";"
-                                       .. dump(core.settings:get_bool("main_menu_technical_settings")) .. "]"
+                                       .. dump(core.settings:get_bool("show_technical_names")) .. "]"
 
        return formspec
 end
@@ -1114,7 +1111,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
        end
 
        if fields["cb_tech_settings"] then
-               core.settings:set("main_menu_technical_settings", fields["cb_tech_settings"])
+               core.settings:set("show_technical_names", fields["cb_tech_settings"])
                core.settings:write()
                core.update_formspec(this:get_formspec())
                return true
diff --git a/builtin/mainmenu/game_theme.lua b/builtin/mainmenu/game_theme.lua
new file mode 100644 (file)
index 0000000..89e1b66
--- /dev/null
@@ -0,0 +1,203 @@
+--Minetest
+--Copyright (C) 2013 sapier
+--
+--This program is free software; you can redistribute it and/or modify
+--it under the terms of the GNU Lesser General Public License as published by
+--the Free Software Foundation; either version 2.1 of the License, or
+--(at your option) any later version.
+--
+--This program is distributed in the hope that it will be useful,
+--but WITHOUT ANY WARRANTY; without even the implied warranty of
+--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--GNU Lesser General Public License for more details.
+--
+--You should have received a copy of the GNU Lesser General Public License along
+--with this program; if not, write to the Free Software Foundation, Inc.,
+--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+mm_game_theme = {}
+
+--------------------------------------------------------------------------------
+function mm_game_theme.init()
+       mm_game_theme.defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
+                                               DIR_DELIM .. "pack" .. DIR_DELIM
+       mm_game_theme.basetexturedir = mm_game_theme.defaulttexturedir
+
+       mm_game_theme.texturepack = core.settings:get("texture_path")
+
+       mm_game_theme.gameid = nil
+
+       mm_game_theme.music_handle = nil
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.update(tab,gamedetails)
+       if tab ~= "singleplayer" then
+               mm_game_theme.reset()
+               return
+       end
+
+       if gamedetails == nil then
+               return
+       end
+
+       mm_game_theme.update_game(gamedetails)
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.reset()
+       mm_game_theme.gameid = nil
+       local have_bg      = false
+       local have_overlay = mm_game_theme.set_generic("overlay")
+
+       if not have_overlay then
+               have_bg = mm_game_theme.set_generic("background")
+       end
+
+       mm_game_theme.clear("header")
+       mm_game_theme.clear("footer")
+       core.set_clouds(false)
+
+       mm_game_theme.set_generic("footer")
+       mm_game_theme.set_generic("header")
+
+       if not have_bg then
+               if core.settings:get_bool("menu_clouds") then
+                       core.set_clouds(true)
+               else
+                       mm_game_theme.set_dirt_bg()
+               end
+       end
+
+       if mm_game_theme.music_handle ~= nil then
+               core.sound_stop(mm_game_theme.music_handle)
+       end
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.update_game(gamedetails)
+       if mm_game_theme.gameid == gamedetails.id then
+               return
+       end
+
+       local have_bg      = false
+       local have_overlay = mm_game_theme.set_game("overlay",gamedetails)
+
+       if not have_overlay then
+               have_bg = mm_game_theme.set_game("background",gamedetails)
+       end
+
+       mm_game_theme.clear("header")
+       mm_game_theme.clear("footer")
+       core.set_clouds(false)
+
+       if not have_bg then
+
+               if core.settings:get_bool("menu_clouds") then
+                       core.set_clouds(true)
+               else
+                       mm_game_theme.set_dirt_bg()
+               end
+       end
+
+       mm_game_theme.set_game("footer",gamedetails)
+       mm_game_theme.set_game("header",gamedetails)
+
+       mm_game_theme.gameid = gamedetails.id
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.clear(identifier)
+       core.set_background(identifier,"")
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.set_generic(identifier)
+       --try texture pack first
+       if mm_game_theme.texturepack ~= nil then
+               local path = mm_game_theme.texturepack .. DIR_DELIM .."menu_" ..
+                                                                               identifier .. ".png"
+               if core.set_background(identifier,path) then
+                       return true
+               end
+       end
+
+       if mm_game_theme.defaulttexturedir ~= nil then
+               local path = mm_game_theme.defaulttexturedir .. DIR_DELIM .."menu_" ..
+                                                                               identifier .. ".png"
+               if core.set_background(identifier,path) then
+                       return true
+               end
+       end
+
+       return false
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.set_game(identifier, gamedetails)
+
+       if gamedetails == nil then
+               return false
+       end
+
+       mm_game_theme.set_music(gamedetails)
+
+       if mm_game_theme.texturepack ~= nil then
+               local path = mm_game_theme.texturepack .. DIR_DELIM ..
+                       gamedetails.id .. "_menu_" .. identifier .. ".png"
+               if core.set_background(identifier, path) then
+                       return true
+               end
+       end
+
+       -- Find out how many randomized textures the game provides
+       local n = 0
+       local filename
+       local menu_files = core.get_dir_list(gamedetails.path .. DIR_DELIM .. "menu", false)
+       for i = 1, #menu_files do
+               filename = identifier .. "." .. i .. ".png"
+               if table.indexof(menu_files, filename) == -1 then
+                       n = i - 1
+                       break
+               end
+       end
+       -- Select random texture, 0 means standard texture
+       n = math.random(0, n)
+       if n == 0 then
+               filename = identifier .. ".png"
+       else
+               filename = identifier .. "." .. n .. ".png"
+       end
+
+       local path = gamedetails.path .. DIR_DELIM .. "menu" ..
+               DIR_DELIM .. filename
+       if core.set_background(identifier, path) then
+               return true
+       end
+
+       return false
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.set_dirt_bg()
+       if mm_game_theme.texturepack ~= nil then
+               local path = mm_game_theme.texturepack .. DIR_DELIM .."default_dirt.png"
+               if core.set_background("background", path, true, 128) then
+                       return true
+               end
+       end
+
+       -- Use universal fallback texture in textures/base/pack
+       local minimalpath = defaulttexturedir .. "menu_bg.png"
+       core.set_background("background", minimalpath, true, 128)
+end
+
+--------------------------------------------------------------------------------
+function mm_game_theme.set_music(gamedetails)
+       if mm_game_theme.music_handle ~= nil then
+               core.sound_stop(mm_game_theme.music_handle)
+       end
+       local music_path = gamedetails.path .. DIR_DELIM .. "menu" .. DIR_DELIM .. "theme"
+       mm_game_theme.music_handle = core.sound_play(music_path, true)
+end
index 43fc57bb99030918c3592b7c5c47a61c5c07a15a..0f551fbb1a1f323c82d6aecce0c86b69942e6060 100644 (file)
@@ -31,7 +31,7 @@ local group_format_template = [[
 #    octaves     = %s,
 #    persistence = %s,
 #    lacunarity  = %s,
-#    flags       = %s
+#    flags       =%s
 # }
 
 ]]
@@ -55,7 +55,11 @@ local function create_minetest_conf_example()
                        end
                        if entry.comment ~= "" then
                                for _, comment_line in ipairs(entry.comment:split("\n", true)) do
-                                       insert(result, "#    " .. comment_line .. "\n")
+                                       if comment_line == "" then
+                                               insert(result, "#\n")
+                                       else
+                                               insert(result, "#    " .. comment_line .. "\n")
+                                       end
                                end
                        end
                        insert(result, "#    type: " .. entry.type)
@@ -73,10 +77,14 @@ local function create_minetest_conf_example()
                        end
                        insert(result, "\n")
                        if group_format == true then
+                               local flags = entry.values[10]
+                               if flags ~= "" then
+                                       flags = " "..flags
+                               end
                                insert(result, sprintf(group_format_template, entry.name, entry.values[1],
                                                entry.values[2], entry.values[3], entry.values[4], entry.values[5],
                                                entry.values[6], entry.values[7], entry.values[8], entry.values[9],
-                                               entry.values[10]))
+                                               flags))
                        else
                                local append
                                if entry.default ~= "" then
@@ -91,7 +99,7 @@ end
 
 local translation_file_header = [[
 // This file is automatically generated
-// It conatins a bunch of fake gettext calls, to tell xgettext about the strings in config files
+// It contains a bunch of fake gettext calls, to tell xgettext about the strings in config files
 // To update it, refer to the bottom of builtin/mainmenu/dlg_settings_advanced.lua
 
 fake_function() {]]
@@ -126,4 +134,3 @@ file = assert(io.open("src/settings_translation_file.cpp", "w"))
 --file = assert(io.open("settings_translation_file.cpp", "w"))
 file:write(create_translation_file())
 file:close()
-
index 2481078e2733ee70aabeadc924befe584f2878ae..94345467734943b5f10134224ea317d3b81817f0 100644 (file)
@@ -35,7 +35,7 @@ dofile(menupath .. DIR_DELIM .. "async_event.lua")
 dofile(menupath .. DIR_DELIM .. "common.lua")
 dofile(menupath .. DIR_DELIM .. "pkgmgr.lua")
 dofile(menupath .. DIR_DELIM .. "serverlistmgr.lua")
-dofile(menupath .. DIR_DELIM .. "textures.lua")
+dofile(menupath .. DIR_DELIM .. "game_theme.lua")
 
 dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
 dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua")
@@ -87,7 +87,7 @@ local function init_globals()
                core.settings:set("menu_last_game", default_game)
        end
 
-       mm_texture.init()
+       mm_game_theme.init()
 
        -- Create main tabview
        local tv_main = tabview_create("maintab", {x = 12, y = 5.4}, {x = 0, y = 0})
@@ -113,7 +113,7 @@ local function init_globals()
        if tv_main.current_tab == "local" then
                local game = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
                if game == nil then
-                       mm_texture.reset()
+                       mm_game_theme.reset()
                end
        end
 
@@ -121,8 +121,6 @@ local function init_globals()
        tv_main:show()
 
        ui.update()
-
-       core.sound_play("main_menu", true)
 end
 
 init_globals()
index 58a4ed8c1e8b68ecf663cdd1e1049391d62fb9f7..072c41f0cd17ad27a6744a0d06cd5c42343e51f7 100644 (file)
@@ -78,34 +78,35 @@ local function load_texture_packs(txtpath, retval)
 
        for _, item in ipairs(list) do
                if item ~= "base" then
-                       local name = item
-
                        local path = txtpath .. DIR_DELIM .. item .. DIR_DELIM
-                       if path == current_texture_path then
-                               name = fgettext("$1 (Enabled)", name)
-                       end
-
                        local conf = Settings(path .. "texture_pack.conf")
+                       local enabled = path == current_texture_path
+
+                       local title = conf:get("title") or item
 
+                       -- list_* is only used if non-nil, else the regular versions are used.
                        retval[#retval + 1] = {
                                name = item,
+                               title = title,
+                               list_name = enabled and fgettext("$1 (Enabled)", item) or nil,
+                               list_title = enabled and fgettext("$1 (Enabled)", title) or nil,
                                author = conf:get("author"),
                                release = tonumber(conf:get("release")) or 0,
-                               list_name = name,
                                type = "txp",
                                path = path,
-                               enabled = path == current_texture_path,
+                               enabled = enabled,
                        }
                end
        end
 end
 
-function get_mods(path,retval,modpack)
+function get_mods(path, virtual_path, retval, modpack)
        local mods = core.get_dir_list(path, true)
 
        for _, name in ipairs(mods) do
                if name:sub(1, 1) ~= "." then
-                       local prefix = path .. DIR_DELIM .. name
+                       local mod_path = path .. DIR_DELIM .. name
+                       local mod_virtual_path = virtual_path .. "/" .. name
                        local toadd = {
                                dir_name = name,
                                parent_dir = path,
@@ -114,18 +115,18 @@ function get_mods(path,retval,modpack)
 
                        -- Get config file
                        local mod_conf
-                       local modpack_conf = io.open(prefix .. DIR_DELIM .. "modpack.conf")
+                       local modpack_conf = io.open(mod_path .. DIR_DELIM .. "modpack.conf")
                        if modpack_conf then
                                toadd.is_modpack = true
                                modpack_conf:close()
 
-                               mod_conf = Settings(prefix .. DIR_DELIM .. "modpack.conf"):to_table()
+                               mod_conf = Settings(mod_path .. DIR_DELIM .. "modpack.conf"):to_table()
                                if mod_conf.name then
                                        name = mod_conf.name
                                        toadd.is_name_explicit = true
                                end
                        else
-                               mod_conf = Settings(prefix .. DIR_DELIM .. "mod.conf"):to_table()
+                               mod_conf = Settings(mod_path .. DIR_DELIM .. "mod.conf"):to_table()
                                if mod_conf.name then
                                        name = mod_conf.name
                                        toadd.is_name_explicit = true
@@ -134,14 +135,16 @@ function get_mods(path,retval,modpack)
 
                        -- Read from config
                        toadd.name = name
+                       toadd.title = mod_conf.title
                        toadd.author = mod_conf.author
                        toadd.release = tonumber(mod_conf.release) or 0
-                       toadd.path = prefix
+                       toadd.path = mod_path
+                       toadd.virtual_path = mod_virtual_path
                        toadd.type = "mod"
 
                        -- Check modpack.txt
                        -- Note: modpack.conf is already checked above
-                       local modpackfile = io.open(prefix .. DIR_DELIM .. "modpack.txt")
+                       local modpackfile = io.open(mod_path .. DIR_DELIM .. "modpack.txt")
                        if modpackfile then
                                modpackfile:close()
                                toadd.is_modpack = true
@@ -153,7 +156,7 @@ function get_mods(path,retval,modpack)
                        elseif toadd.is_modpack then
                                toadd.type = "modpack"
                                toadd.is_modpack = true
-                               get_mods(prefix, retval, name)
+                               get_mods(mod_path, mod_virtual_path, retval, name)
                        end
                end
        end
@@ -181,21 +184,6 @@ function pkgmgr.get_texture_packs()
 end
 
 --------------------------------------------------------------------------------
-function pkgmgr.extract(modfile)
-       if modfile.type == "zip" then
-               local tempfolder = os.tempfolder()
-
-               if tempfolder ~= nil and
-                       tempfolder ~= "" then
-                       core.create_dir(tempfolder)
-                       if core.extract_zip(modfile.name,tempfolder) then
-                               return tempfolder
-                       end
-               end
-       end
-       return nil
-end
-
 function pkgmgr.get_folder_type(path)
        local testfile = io.open(path .. DIR_DELIM .. "init.lua","r")
        if testfile ~= nil then
@@ -349,7 +337,7 @@ function pkgmgr.identify_modname(modpath,filename)
        return nil
 end
 --------------------------------------------------------------------------------
-function pkgmgr.render_packagelist(render_list)
+function pkgmgr.render_packagelist(render_list, use_technical_names)
        if not render_list then
                if not pkgmgr.global_mods then
                        pkgmgr.refresh_globals()
@@ -385,7 +373,12 @@ function pkgmgr.render_packagelist(render_list)
                else
                        retval[#retval + 1] = "0"
                end
-               retval[#retval + 1] = core.formspec_escape(v.list_name or v.name)
+
+               if use_technical_names then
+                       retval[#retval + 1] = core.formspec_escape(v.list_name or v.name)
+               else
+                       retval[#retval + 1] = core.formspec_escape(v.list_title or v.list_name or v.title or v.name)
+               end
        end
 
        return table.concat(retval, ",")
@@ -412,6 +405,14 @@ function pkgmgr.is_modpack_entirely_enabled(data, name)
        return true
 end
 
+local function disable_all_by_name(list, name, except)
+       for i=1, #list do
+               if list[i].name == name and list[i] ~= except then
+                       list[i].enabled = false
+               end
+       end
+end
+
 ---------- toggles or en/disables a mod or modpack and its dependencies --------
 local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod)
        if not mod.is_modpack then
@@ -420,13 +421,16 @@ local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mo
                        toset = not mod.enabled
                end
                if mod.enabled ~= toset then
-                       mod.enabled = toset
                        toggled_mods[#toggled_mods+1] = mod.name
                end
                if toset then
                        -- Mark this mod for recursive dependency traversal
                        enabled_mods[mod.name] = true
+
+                       -- Disable other mods with the same name
+                       disable_all_by_name(list, mod.name, mod)
                end
+               mod.enabled = toset
        else
                -- Toggle or en/disable every mod in the modpack,
                -- interleaved unsupported
@@ -451,7 +455,7 @@ function pkgmgr.enable_mod(this, toset)
        local enabled_mods = {}
        toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod)
 
-       if not toset then
+       if next(enabled_mods) == nil then
                -- Mod(s) were disabled, so no dependencies need to be enabled
                table.sort(toggled_mods)
                core.log("info", "Following mods were disabled: " ..
@@ -461,11 +465,16 @@ function pkgmgr.enable_mod(this, toset)
 
        -- Enable mods' depends after activation
 
-       -- Make a list of mod ids indexed by their names
+       -- Make a list of mod ids indexed by their names. Among mods with the
+       -- same name, enabled mods take precedence, after which game mods take
+       -- precedence, being last in the mod list.
        local mod_ids = {}
        for id, mod2 in pairs(list) do
                if mod2.type == "mod" and not mod2.is_modpack then
-                       mod_ids[mod2.name] = id
+                       local prev_id = mod_ids[mod2.name]
+                       if not prev_id or not list[prev_id].enabled then
+                               mod_ids[mod2.name] = id
+                       end
                end
        end
 
@@ -482,6 +491,7 @@ function pkgmgr.enable_mod(this, toset)
                        end
                end
        end
+
        -- If sp is 0, every dependency is already activated
        while sp > 0 do
                local name = to_enable[sp]
@@ -494,14 +504,14 @@ function pkgmgr.enable_mod(this, toset)
                                core.log("warning", "Mod dependency \"" .. name ..
                                        "\" not found!")
                        else
-                               if mod_to_enable.enabled == false then
+                               if not mod_to_enable.enabled then
                                        mod_to_enable.enabled = true
                                        toggled_mods[#toggled_mods+1] = mod_to_enable.name
                                end
                                -- Push the dependencies of the dependency onto the stack
                                local depends = pkgmgr.get_dependencies(mod_to_enable.path)
                                for i = 1, #depends do
-                                       if not enabled_mods[name] then
+                                       if not enabled_mods[depends[i]] then
                                                sp = sp+1
                                                to_enable[sp] = depends[i]
                                        end
@@ -561,11 +571,10 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
                local from = basefolder and basefolder.path or path
                if targetpath then
                        core.delete_dir(targetpath)
-                       core.create_dir(targetpath)
                else
                        targetpath = core.get_texturepath() .. DIR_DELIM .. basename
                end
-               if not core.copy_dir(from, targetpath) then
+               if not core.copy_dir(from, targetpath, false) then
                        return nil,
                                fgettext("Failed to install $1 to $2", basename, targetpath)
                end
@@ -586,7 +595,6 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
                -- Get destination name for modpack
                if targetpath then
                        core.delete_dir(targetpath)
-                       core.create_dir(targetpath)
                else
                        local clean_path = nil
                        if basename ~= nil then
@@ -610,7 +618,6 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
 
                if targetpath then
                        core.delete_dir(targetpath)
-                       core.create_dir(targetpath)
                else
                        local targetfolder = basename
                        if targetfolder == nil then
@@ -636,14 +643,13 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
 
                if targetpath then
                        core.delete_dir(targetpath)
-                       core.create_dir(targetpath)
                else
                        targetpath = core.get_gamepath() .. DIR_DELIM .. basename
                end
        end
 
        -- Copy it
-       if not core.copy_dir(basefolder.path, targetpath) then
+       if not core.copy_dir(basefolder.path, targetpath, false) then
                return nil,
                        fgettext("Failed to install $1 to $2", basename, targetpath)
        end
@@ -657,23 +663,6 @@ function pkgmgr.install_dir(type, path, basename, targetpath)
        return targetpath, nil
 end
 
---------------------------------------------------------------------------------
-function pkgmgr.install(type, modfilename, basename, dest)
-       local archive_info = pkgmgr.identify_filetype(modfilename)
-       local path = pkgmgr.extract(archive_info)
-
-       if path == nil then
-               return nil,
-                       fgettext("Install: file: \"$1\"", archive_info.name) .. "\n" ..
-                       fgettext("Install: Unsupported file type \"$1\" or broken archive",
-                               archive_info.type)
-       end
-
-       local targetpath, msg = pkgmgr.install_dir(type, path, basename, dest)
-       core.delete_dir(path)
-       return targetpath, msg
-end
-
 --------------------------------------------------------------------------------
 function pkgmgr.prepareclientmodlist(data)
        local retval = {}
@@ -683,9 +672,8 @@ function pkgmgr.prepareclientmodlist(data)
        --read clientmods
        local modpath = core.get_clientmodpath()
 
-       if modpath ~= nil and
-               modpath ~= "" then
-               get_mods(modpath,clientmods)
+       if modpath ~= nil and modpath ~= "" then
+               get_mods(modpath, "clientmods", clientmods)
        end
 
        for i=1,#clientmods,1 do
@@ -730,16 +718,15 @@ function pkgmgr.preparemodlist(data)
        local game_mods = {}
 
        --read global mods
-       local modpath = core.get_modpath()
-
-       if modpath ~= nil and
-               modpath ~= "" then
-               get_mods(modpath,global_mods)
+       local modpaths = core.get_modpaths()
+       for key, modpath in pairs(modpaths) do
+               get_mods(modpath, key, global_mods)
        end
 
        for i=1,#global_mods,1 do
                global_mods[i].type = "mod"
                global_mods[i].loc = "global"
+               global_mods[i].enabled = false
                retval[#retval + 1] = global_mods[i]
        end
 
@@ -773,22 +760,37 @@ function pkgmgr.preparemodlist(data)
                                DIR_DELIM .. "world.mt"
 
        local worldfile = Settings(filename)
-
-       for key,value in pairs(worldfile:to_table()) do
+       for key, value in pairs(worldfile:to_table()) do
                if key:sub(1, 9) == "load_mod_" then
                        key = key:sub(10)
-                       local element = nil
-                       for i=1,#retval,1 do
+                       local mod_found = false
+
+                       local fallback_found = false
+                       local fallback_mod = nil
+
+                       for i=1, #retval do
                                if retval[i].name == key and
-                                       not retval[i].is_modpack then
-                                       element = retval[i]
-                                       break
+                                               not retval[i].is_modpack then
+                                       if core.is_yes(value) or retval[i].virtual_path == value then
+                                               retval[i].enabled = true
+                                               mod_found = true
+                                               break
+                                       elseif fallback_found then
+                                               -- Only allow fallback if only one mod matches
+                                               fallback_mod = nil
+                                       else
+                                               fallback_found = true
+                                               fallback_mod = retval[i]
+                                       end
                                end
                        end
-                       if element ~= nil then
-                               element.enabled = value ~= "false" and value ~= "nil" and value
-                       else
-                               core.log("info", "Mod: " .. key .. " " .. dump(value) .. " but not found")
+
+                       if not mod_found then
+                               if fallback_mod and value:find("/") then
+                                       fallback_mod.enabled = true
+                               else
+                                       core.log("info", "Mod: " .. key .. " " .. dump(value) .. " but not found")
+                               end
                        end
                end
        end
@@ -871,45 +873,6 @@ function pkgmgr.refresh_globals()
        pkgmgr.clientmods:set_sortmode("alphabetic")
 end
 
---------------------------------------------------------------------------------
-function pkgmgr.identify_filetype(name)
-
-       if name:sub(-3):lower() == "zip" then
-               return {
-                               name = name,
-                               type = "zip"
-                               }
-       end
-
-       if name:sub(-6):lower() == "tar.gz" or
-               name:sub(-3):lower() == "tgz"then
-               return {
-                               name = name,
-                               type = "tgz"
-                               }
-       end
-
-       if name:sub(-6):lower() == "tar.bz2" then
-               return {
-                               name = name,
-                               type = "tbz"
-                               }
-       end
-
-       if name:sub(-2):lower() == "7z" then
-               return {
-                               name = name,
-                               type = "7z"
-                               }
-       end
-
-       return {
-               name = name,
-               type = "ukn"
-       }
-end
-
-
 --------------------------------------------------------------------------------
 function pkgmgr.find_by_gameid(gameid)
        for i=1,#pkgmgr.games,1 do
@@ -925,7 +888,7 @@ function pkgmgr.get_game_mods(gamespec, retval)
        if gamespec ~= nil and
                gamespec.gamemods_path ~= nil and
                gamespec.gamemods_path ~= "" then
-               get_mods(gamespec.gamemods_path, retval)
+               get_mods(gamespec.gamemods_path, ("games/%s/mods"):format(gamespec.id), retval)
        end
 end
 
index cb566f773bd94dbd4c0cff6cc480bc6ba6c96d2d..3336786ba4ea9e56d4cafbf29a4eda18d632da28 100644 (file)
@@ -38,32 +38,35 @@ local core_developers = {
        "Lars Hofhansl <larsh@apache.org>",
        "Pierre-Yves Rollo <dev@pyrollo.com>",
        "v-rob <robinsonvincent89@gmail.com>",
+       "hecks",
+       "Hugues Ross <hugues.ross@gmail.com>",
+       "Dmitry Kostenko (x2048) <codeforsmile@gmail.com>",
 }
 
 -- For updating active/previous contributors, see the script in ./util/gather_git_credits.py
 
 local active_contributors = {
-       "Wuzzy [devtest game, visual corrections]",
-       "Zughy [Visual improvements, various fixes]",
-       "Maksim (MoNTE48) [Android]",
+       "Wuzzy [I18n for builtin, liquid features, fixes]",
+       "Zughy [Various features and fixes]",
        "numzero [Graphics and rendering]",
-       "appgurueu [Various internal fixes]",
-       "Desour [Formspec and vector API changes]",
-       "HybridDog [Rendering fixes and documentation]",
-       "Hugues Ross [Graphics-related improvements]",
-       "ANAND (ClobberXD) [Mouse buttons rebinding]",
-       "luk3yx [Fixes]",
-       "hecks [Audiovisuals, Lua API]",
-       "LoneWolfHT [Object crosshair, documentation fixes]",
-       "Lejo [Server-related improvements]",
-       "EvidenceB [Compass HUD element]",
-       "Paul Ouellette (pauloue) [Lua API, documentation]",
-       "TheTermos [Collision detection, physics]",
+       "Desour [Internal fixes, Clipboard on X11]",
+       "Lars Müller [Various internal fixes]",
+       "JosiahWI [CMake, cleanups and fixes]",
+       "HybridDog [builtin, documentation]",
+       "Jude Melton-Houghton [Database implementation]",
+       "savilli [Fixes]",
+       "Liso [Shadow Mapping]",
+       "MoNTE48 [Build fix]",
+       "Jean-Patrick Guerrero (kilbith) [Fixes]",
+       "ROllerozxa [Code cleanups]",
+       "Lejo [bitop library integration]",
+       "LoneWolfHT [Build fixes]",
+       "NeroBurner [Joystick]",
+       "Elias Fleckenstein [Internal fixes]",
        "David CARLIER [Unix & Haiku build fixes]",
-       "dcbrwn [Object shading]",
-       "Elias Fleckenstein [API features/fixes]",
-       "Jean-Patrick Guerrero (kilbith) [model element, visual fixes]",
-       "k.h.lai [Memory leak fixes, documentation]",
+       "pecksin [Clickable web links]",
+       "srfqi [Android & rendering fixes]",
+       "EvidenceB [Formspec]",
 }
 
 local previous_core_developers = {
@@ -80,6 +83,7 @@ local previous_core_developers = {
        "Zeno",
        "ShadowNinja <shadowninja@minetest.net>",
        "Auke Kok (sofar) <sofar@foo-projects.org>",
+       "Aaron Suen <warr1024@gmail.com>",
 }
 
 local previous_contributors = {
@@ -90,10 +94,10 @@ local previous_contributors = {
        "MirceaKitsune <mirceakitsune@gmail.com>",
        "Constantin Wenger (SpeedProg)",
        "Ciaran Gultnieks (CiaranG)",
-       "stujones11 [Android UX improvements]",
-       "Rogier <rogier777@gmail.com> [Fixes]",
-       "Gregory Currie (gregorycu) [optimisation]",
-       "srifqi [Fixes]",
+       "Paul Ouellette (pauloue)",
+       "stujones11",
+       "Rogier <rogier777@gmail.com>",
+       "Gregory Currie (gregorycu)",
        "JacobF",
        "Jeija <jeija@mesecons.net> [HTTP, particles]",
 }
index 1bffeeb223234353a51fd65f301255254e1625a4..a366d4ab4a11e3907c928ebab755903408e384cf 100644 (file)
@@ -88,12 +88,14 @@ local function get_formspec(tabview, name, tabdata)
                tabdata.selected_pkg = 1
        end
 
+       local use_technical_names = core.settings:get_bool("show_technical_names")
+
 
        local retval =
                "label[0.05,-0.25;".. fgettext("Installed Packages:") .. "]" ..
                "tablecolumns[color;tree;text]" ..
                "table[0,0.25;5.1,4.3;pkglist;" ..
-               pkgmgr.render_packagelist(packages) ..
+               pkgmgr.render_packagelist(packages, use_technical_names) ..
                ";" .. tabdata.selected_pkg .. "]" ..
                "button[0,4.85;5.25,0.5;btn_contentdb;".. fgettext("Browse online content") .. "]"
 
@@ -124,9 +126,17 @@ local function get_formspec(tabview, name, tabdata)
                        desc = info.description
                end
 
+               local title_and_name
+               if selected_pkg.type == "game" then
+                       title_and_name = selected_pkg.name
+               else
+                       title_and_name = (selected_pkg.title or selected_pkg.name) .. "\n" ..
+                               core.colorize("#BFBFBF", selected_pkg.name)
+               end
+
                retval = retval ..
                                "image[5.5,0;3,2;" .. core.formspec_escape(modscreenshot) .. "]" ..
-                               "label[8.25,0.6;" .. core.formspec_escape(selected_pkg.name) .. "]" ..
+                               "label[8.25,0.6;" .. core.formspec_escape(title_and_name) .. "]" ..
                                "box[5.5,2.2;6.15,2.35;#000]"
 
                if selected_pkg.type == "mod" then
@@ -214,6 +224,9 @@ local function handle_doubleclick(pkg, pkg_name)
                        core.settings:set("texture_path", pkg.path)
                end
                packages = nil
+
+               mm_game_theme.init()
+               mm_game_theme.reset()
        elseif pkg.is_clientside then
                pkgmgr.enable_mod({data = {list = packages, selected_mod = pkg_name}})
                packages = nil
@@ -276,17 +289,17 @@ local function handle_buttons(tabview, fields, tabname, tabdata)
                return true
        end
 
-       if fields.btn_mod_mgr_use_txp then
-               local txp = packages:get_list()[tabdata.selected_pkg]
-               core.settings:set("texture_path", txp.path)
-               packages = nil
-               return true
-       end
-
+       if fields.btn_mod_mgr_use_txp or fields.btn_mod_mgr_disable_txp then
+               local txp_path = ""
+               if fields.btn_mod_mgr_use_txp then
+                       txp_path = packages:get_list()[tabdata.selected_pkg].path
+               end
 
-       if fields.btn_mod_mgr_disable_txp then
-               core.settings:set("texture_path", "")
+               core.settings:set("texture_path", txp_path)
                packages = nil
+
+               mm_game_theme.init()
+               mm_game_theme.reset()
                return true
        end
 
index be5f905acff9d0bd9da06f1bc6e12f40eaa447af..e77c6f04de368ea1e967099144003f04e4e244e8 100644 (file)
@@ -33,10 +33,30 @@ if enable_gamebar then
                return game
        end
 
+       -- Apply menu changes from given game
+       function apply_game(game)
+               core.set_topleft_text(game.name)
+               core.settings:set("menu_last_game", game.id)
+               menudata.worldlist:set_filtercriteria(game.id)
+
+               mm_game_theme.update("singleplayer", game) -- this refreshes the formspec
+
+               local index = filterlist.get_current_index(menudata.worldlist,
+                       tonumber(core.settings:get("mainmenu_last_selected_world")))
+               if not index or index < 1 then
+                       local selected = core.get_textlist_index("sp_worlds")
+                       if selected ~= nil and selected < #menudata.worldlist:get_list() then
+                               index = selected
+                       else
+                               index = #menudata.worldlist:get_list()
+                       end
+               end
+               menu_worldmt_legacy(index)
+       end
+
        function singleplayer_refresh_gamebar()
 
                local old_bar = ui.find_by_name("game_button_bar")
-
                if old_bar ~= nil then
                        old_bar:delete()
                end
@@ -51,26 +71,10 @@ if enable_gamebar then
                                return true
                        end
 
-                       for key,value in pairs(fields) do
-                               for j=1,#pkgmgr.games,1 do
-                                       if ("game_btnbar_" .. pkgmgr.games[j].id == key) then
-                                               mm_texture.update("singleplayer", pkgmgr.games[j])
-                                               core.set_topleft_text(pkgmgr.games[j].name)
-                                               core.settings:set("menu_last_game",pkgmgr.games[j].id)
-                                               menudata.worldlist:set_filtercriteria(pkgmgr.games[j].id)
-                                               local index = filterlist.get_current_index(menudata.worldlist,
-                                                       tonumber(core.settings:get("mainmenu_last_selected_world")))
-                                               if not index or index < 1 then
-                                                       local selected = core.get_textlist_index("sp_worlds")
-                                                       if selected ~= nil and selected < #menudata.worldlist:get_list() then
-                                                               index = selected
-                                                       else
-                                                               index = #menudata.worldlist:get_list()
-                                                       end
-                                               end
-                                               menu_worldmt_legacy(index)
-                                               return true
-                                       end
+                       for _, game in ipairs(pkgmgr.games) do
+                               if fields["game_btnbar_" .. game.id] then
+                                       apply_game(game)
+                                       return true
                                end
                        end
                end
@@ -79,25 +83,22 @@ if enable_gamebar then
                        game_buttonbar_button_handler,
                        {x=-0.3,y=5.9}, "horizontal", {x=12.4,y=1.15})
 
-               for i=1,#pkgmgr.games,1 do
-                       local btn_name = "game_btnbar_" .. pkgmgr.games[i].id
+               for _, game in ipairs(pkgmgr.games) do
+                       local btn_name = "game_btnbar_" .. game.id
 
                        local image = nil
                        local text = nil
-                       local tooltip = core.formspec_escape(pkgmgr.games[i].name)
+                       local tooltip = core.formspec_escape(game.name)
 
-                       if pkgmgr.games[i].menuicon_path ~= nil and
-                               pkgmgr.games[i].menuicon_path ~= "" then
-                               image = core.formspec_escape(pkgmgr.games[i].menuicon_path)
+                       if (game.menuicon_path or "") ~= "" then
+                               image = core.formspec_escape(game.menuicon_path)
                        else
-
-                               local part1 = pkgmgr.games[i].id:sub(1,5)
-                               local part2 = pkgmgr.games[i].id:sub(6,10)
-                               local part3 = pkgmgr.games[i].id:sub(11)
+                               local part1 = game.id:sub(1,5)
+                               local part2 = game.id:sub(6,10)
+                               local part3 = game.id:sub(11)
 
                                text = part1 .. "\n" .. part2
-                               if part3 ~= nil and
-                                       part3 ~= "" then
+                               if part3 ~= "" then
                                        text = text .. "\n" .. part3
                                end
                        end
@@ -147,8 +148,12 @@ local function get_formspec(tabview, name, tabdata)
                                tonumber(core.settings:get("mainmenu_last_selected_world")))
        local list = menudata.worldlist:get_list()
        local world = list and index and list[index]
-       local gameid = world and world.gameid
-       local game = gameid and pkgmgr.find_by_gameid(gameid)
+       local game
+       if world then
+               game = pkgmgr.find_by_gameid(world.gameid)
+       else
+               game = current_game()
+       end
        local disabled_settings = get_disabled_settings(game)
 
        local creative, damage, host = "", "", ""
@@ -182,7 +187,7 @@ local function get_formspec(tabview, name, tabdata)
                        damage ..
                        host ..
                        "textlist[3.9,0.4;7.9,3.45;sp_worlds;" ..
-                       menu_render_worldlist() ..
+                       menu_render_worldlist(not enable_gamebar) ..
                        ";" .. index .. "]"
 
        if core.settings:get_bool("enable_server") and disabled_settings["enable_server"] == nil then
@@ -319,11 +324,11 @@ local function main_button_handler(this, fields, name, tabdata)
        end
 
        if fields["world_create"] ~= nil then
-               local create_world_dlg = create_create_world_dlg(true)
+               local create_world_dlg = create_create_world_dlg(enable_gamebar)
                create_world_dlg:set_parent(this)
                this:hide()
                create_world_dlg:show()
-               mm_texture.update("singleplayer", current_game())
+               mm_game_theme.update("singleplayer", current_game())
                return true
        end
 
@@ -340,7 +345,7 @@ local function main_button_handler(this, fields, name, tabdata)
                                delete_world_dlg:set_parent(this)
                                this:hide()
                                delete_world_dlg:show()
-                               mm_texture.update("singleplayer",current_game())
+                               mm_game_theme.update("singleplayer",current_game())
                        end
                end
 
@@ -358,7 +363,7 @@ local function main_button_handler(this, fields, name, tabdata)
                                configdialog:set_parent(this)
                                this:hide()
                                configdialog:show()
-                               mm_texture.update("singleplayer",current_game())
+                               mm_game_theme.update("singleplayer",current_game())
                        end
                end
 
@@ -371,11 +376,8 @@ if enable_gamebar then
        function on_change(type, old_tab, new_tab)
                if (type == "ENTER") then
                        local game = current_game()
-
                        if game then
-                               menudata.worldlist:set_filtercriteria(game.id)
-                               core.set_topleft_text(game.name)
-                               mm_texture.update("singleplayer",game)
+                               apply_game(game)
                        end
 
                        singleplayer_refresh_gamebar()
@@ -387,7 +389,7 @@ if enable_gamebar then
                                gamebar:hide()
                        end
                        core.set_topleft_text("")
-                       mm_texture.update(new_tab,nil)
+                       mm_game_theme.update(new_tab,nil)
                end
        end
 end
index f06e3587224746c39afc27a7976035047ea73a9d..0e761d324823548a60f8e31bde51e0d3aaad2711 100644 (file)
@@ -247,7 +247,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
                adv_settings_dlg:set_parent(this)
                this:hide()
                adv_settings_dlg:show()
-               --mm_texture.update("singleplayer", current_game())
+               --mm_game_theme.update("singleplayer", current_game())
                return true
        end
        if fields["cb_smooth_lighting"] then
@@ -275,13 +275,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
                return true
        end
        if fields["cb_shaders"] then
-               if (core.settings:get("video_driver") == "direct3d8" or
-                               core.settings:get("video_driver") == "direct3d9") then
-                       core.settings:set("enable_shaders", "false")
-                       gamedata.errormessage = fgettext("To enable shaders the OpenGL driver needs to be used.")
-               else
-                       core.settings:set("enable_shaders", fields["cb_shaders"])
-               end
+               core.settings:set("enable_shaders", fields["cb_shaders"])
                return true
        end
        if fields["cb_tonemapping"] then
@@ -370,11 +364,11 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
                core.settings:set("enable_dynamic_shadows", "false")
        else
                local shadow_presets = {
-                       [2] = { 80,  512,  "true", 0, "false" },
-                       [3] = { 120, 1024, "true", 1, "false" },
-                       [4] = { 350, 2048, "true", 1, "false" },
-                       [5] = { 350, 2048, "true", 2,  "true" },
-                       [6] = { 450, 4096, "true", 2,  "true" },
+                       [2] = { 55,  512,  "true", 0, "false" },
+                       [3] = { 82,  1024, "true", 1, "false" },
+                       [4] = { 240, 2048, "true", 1, "false" },
+                       [5] = { 240, 2048, "true", 2,  "true" },
+                       [6] = { 300, 4096, "true", 2,  "true" },
                }
                local s = shadow_presets[table.indexof(labels.shadow_levels, fields["dd_shadows"])]
                if s then
index a091959fbbf45bca91fa74349e030c6f3e397a6f..ab7a6c60c85e5a27b1890ca1aa9f4cf9dcb83ef1 100644 (file)
@@ -1,4 +1,5 @@
 _G.core = {}
+_G.vector = {metatable = {}}
 _G.unpack = table.unpack
 _G.serverlistmgr = {}
 
diff --git a/builtin/mainmenu/textures.lua b/builtin/mainmenu/textures.lua
deleted file mode 100644 (file)
index a3acbbd..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
---Minetest
---Copyright (C) 2013 sapier
---
---This program is free software; you can redistribute it and/or modify
---it under the terms of the GNU Lesser General Public License as published by
---the Free Software Foundation; either version 2.1 of the License, or
---(at your option) any later version.
---
---This program is distributed in the hope that it will be useful,
---but WITHOUT ANY WARRANTY; without even the implied warranty of
---MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
---GNU Lesser General Public License for more details.
---
---You should have received a copy of the GNU Lesser General Public License along
---with this program; if not, write to the Free Software Foundation, Inc.,
---51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-
-mm_texture = {}
-
---------------------------------------------------------------------------------
-function mm_texture.init()
-       mm_texture.defaulttexturedir = core.get_texturepath() .. DIR_DELIM .. "base" ..
-                                               DIR_DELIM .. "pack" .. DIR_DELIM
-       mm_texture.basetexturedir = mm_texture.defaulttexturedir
-
-       mm_texture.texturepack = core.settings:get("texture_path")
-
-       mm_texture.gameid = nil
-end
-
---------------------------------------------------------------------------------
-function mm_texture.update(tab,gamedetails)
-       if tab ~= "singleplayer" then
-               mm_texture.reset()
-               return
-       end
-
-       if gamedetails == nil then
-               return
-       end
-
-       mm_texture.update_game(gamedetails)
-end
-
---------------------------------------------------------------------------------
-function mm_texture.reset()
-       mm_texture.gameid = nil
-       local have_bg      = false
-       local have_overlay = mm_texture.set_generic("overlay")
-
-       if not have_overlay then
-               have_bg = mm_texture.set_generic("background")
-       end
-
-       mm_texture.clear("header")
-       mm_texture.clear("footer")
-       core.set_clouds(false)
-
-       mm_texture.set_generic("footer")
-       mm_texture.set_generic("header")
-
-       if not have_bg then
-               if core.settings:get_bool("menu_clouds") then
-                       core.set_clouds(true)
-               else
-                       mm_texture.set_dirt_bg()
-               end
-       end
-end
-
---------------------------------------------------------------------------------
-function mm_texture.update_game(gamedetails)
-       if mm_texture.gameid == gamedetails.id then
-               return
-       end
-
-       local have_bg      = false
-       local have_overlay = mm_texture.set_game("overlay",gamedetails)
-
-       if not have_overlay then
-               have_bg = mm_texture.set_game("background",gamedetails)
-       end
-
-       mm_texture.clear("header")
-       mm_texture.clear("footer")
-       core.set_clouds(false)
-
-       if not have_bg then
-
-               if core.settings:get_bool("menu_clouds") then
-                       core.set_clouds(true)
-               else
-                       mm_texture.set_dirt_bg()
-               end
-       end
-
-       mm_texture.set_game("footer",gamedetails)
-       mm_texture.set_game("header",gamedetails)
-
-       mm_texture.gameid = gamedetails.id
-end
-
---------------------------------------------------------------------------------
-function mm_texture.clear(identifier)
-       core.set_background(identifier,"")
-end
-
---------------------------------------------------------------------------------
-function mm_texture.set_generic(identifier)
-       --try texture pack first
-       if mm_texture.texturepack ~= nil then
-               local path = mm_texture.texturepack .. DIR_DELIM .."menu_" ..
-                                                                               identifier .. ".png"
-               if core.set_background(identifier,path) then
-                       return true
-               end
-       end
-
-       if mm_texture.defaulttexturedir ~= nil then
-               local path = mm_texture.defaulttexturedir .. DIR_DELIM .."menu_" ..
-                                                                               identifier .. ".png"
-               if core.set_background(identifier,path) then
-                       return true
-               end
-       end
-
-       return false
-end
-
---------------------------------------------------------------------------------
-function mm_texture.set_game(identifier, gamedetails)
-
-       if gamedetails == nil then
-               return false
-       end
-
-       if mm_texture.texturepack ~= nil then
-               local path = mm_texture.texturepack .. DIR_DELIM ..
-                       gamedetails.id .. "_menu_" .. identifier .. ".png"
-               if core.set_background(identifier, path) then
-                       return true
-               end
-       end
-
-       -- Find out how many randomized textures the game provides
-       local n = 0
-       local filename
-       local menu_files = core.get_dir_list(gamedetails.path .. DIR_DELIM .. "menu", false)
-       for i = 1, #menu_files do
-               filename = identifier .. "." .. i .. ".png"
-               if table.indexof(menu_files, filename) == -1 then
-                       n = i - 1
-                       break
-               end
-       end
-       -- Select random texture, 0 means standard texture
-       n = math.random(0, n)
-       if n == 0 then
-               filename = identifier .. ".png"
-       else
-               filename = identifier .. "." .. n .. ".png"
-       end
-
-       local path = gamedetails.path .. DIR_DELIM .. "menu" ..
-               DIR_DELIM .. filename
-       if core.set_background(identifier, path) then
-               return true
-       end
-
-       return false
-end
-
-function mm_texture.set_dirt_bg()
-       if mm_texture.texturepack ~= nil then
-               local path = mm_texture.texturepack .. DIR_DELIM .."default_dirt.png"
-               if core.set_background("background", path, true, 128) then
-                       return true
-               end
-       end
-
-       -- Use universal fallback texture in textures/base/pack
-       local minimalpath = defaulttexturedir .. "menu_bg.png"
-       core.set_background("background", minimalpath, true, 128)
-end
index 6b951a2c2d57647b3068e531b27213a128566bfb..f80314b3283166bc8fa5bc5bf4a9ddaf8ce2d8c2 100644 (file)
@@ -102,8 +102,9 @@ local function instrument(def)
                -- also called https://en.wikipedia.org/wiki/Continuation_passing_style
                -- Compared to table creation and unpacking it won't lose `nil` returns
                -- and is expected to be faster
-               -- `measure` will be executed after time() and func(...)
-               return measure(modname, instrument_name, time(), func(...))
+               -- `measure` will be executed after func(...)
+               local start = time()
+               return measure(modname, instrument_name, start, func(...))
        end
 end
 
index e023aeab7416d442ee0acb996597104c6646428a..2e0bb560a7739e406de88063cfdc224bc57d54a1 100644 (file)
@@ -146,17 +146,17 @@ enable_joysticks (Enable joysticks) bool false
 joystick_id (Joystick ID) int 0
 
 #    The type of joystick
-joystick_type (Joystick type) enum auto auto,generic,xbox
+joystick_type (Joystick type) enum auto auto,generic,xbox,dragonrise_gamecube
 
 #    The time in seconds it takes between repeated events
 #    when holding down a joystick button combination.
 repeat_joystick_button_time (Joystick button repetition interval) float 0.17 0.001
 
-#    The deadzone of the joystick
-joystick_deadzone (Joystick deadzone) int 2048
+#    The dead zone of the joystick
+joystick_deadzone (Joystick dead zone) int 2048
 
 #    The sensitivity of the joystick axes for moving the
-#    ingame view frustum around.
+#    in-game view frustum around.
 joystick_frustum_sensitivity (Joystick frustum sensitivity) float 170
 
 #    Key for moving the player forward.
@@ -463,9 +463,9 @@ keymap_decrease_viewing_range_min (View range decrease key) key -
 
 [**Basic]
 
-#    Whether nametag backgrounds should be shown by default.
+#    Whether name tag backgrounds should be shown by default.
 #    Mods may still set a background.
-show_nametag_backgrounds (Show nametag backgrounds by default) bool true
+show_nametag_backgrounds (Show name tag backgrounds by default) bool true
 
 #    Enable vertex buffer objects.
 #    This should greatly improve graphics performance.
@@ -487,6 +487,10 @@ connected_glass (Connect glass) bool false
 #    Disable for speed or for different looks.
 smooth_lighting (Smooth lighting) bool true
 
+#    Enables tradeoffs that reduce CPU load or increase rendering performance
+#    at the expense of minor visual glitches that do not impact game playability.
+performance_tradeoffs (Tradeoffs for performance) bool false
+
 #    Clouds are a client side effect.
 enable_clouds (Clouds) bool true
 
@@ -501,7 +505,7 @@ enable_particles (Digging particles) bool true
 
 [**Filtering]
 
-#    Use mip mapping to scale textures. May slightly increase performance,
+#    Use mipmapping to scale textures. May slightly increase performance,
 #    especially when using a high resolution texture pack.
 #    Gamma correct downscaling is not supported.
 mip_map (Mipmapping) bool false
@@ -600,9 +604,10 @@ enable_waving_plants (Waving plants) bool false
 #    Requires shaders to be enabled.
 enable_dynamic_shadows (Dynamic shadows) bool false
 
-#    Set the shadow strength.
+#    Set the shadow strength gamma.
+#    Adjusts the intensity of in-game dynamic shadows.
 #    Lower value means lighter shadows, higher value means darker shadows.
-shadow_strength (Shadow strength) float 0.2 0.05 1.0
+shadow_strength_gamma (Shadow strength gamma) float 1.0 0.1 10.0
 
 #    Maximum distance to render shadows.
 shadow_map_max_distance (Shadow map max distance in nodes to render shadows) float 120.0 10.0 1000.0
@@ -621,12 +626,12 @@ shadow_map_texture_32bit (Shadow map texture in 32 bits) bool true
 #    On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering.
 shadow_poisson_filter (Poisson filtering) bool true
 
-#   Define shadow filtering quality
+#   Define shadow filtering quality.
 #   This simulates the soft shadows effect by applying a PCF or Poisson disk
 #   but also uses more resources.
 shadow_filters (Shadow filter quality) enum 1 0,1,2
 
-#    Enable colored shadows. 
+#    Enable colored shadows.
 #    On true translucent nodes cast colored shadows. This is expensive.
 shadow_map_color (Colored shadows) bool false
 
@@ -638,10 +643,10 @@ shadow_update_frames (Map shadows update frames) int 8 1 16
 
 #    Set the soft shadow radius size.
 #    Lower values mean sharper shadows, bigger values mean softer shadows.
-#    Minimum value: 1.0; maxiumum value: 10.0
+#    Minimum value: 1.0; maximum value: 10.0
 shadow_soft_radius (Soft shadow radius) float 1.0 1.0 10.0
 
-#    Set the tilt of Sun/Moon orbit in degrees
+#    Set the tilt of Sun/Moon orbit in degrees.
 #    Value of 0 means no tilt / vertical orbit.
 #    Minimum value: 0.0; maximum value: 60.0
 shadow_sky_body_orbit_tilt (Sky Body Orbit Tilt) float 0.0 0.0 60.0
@@ -801,7 +806,7 @@ desynchronize_mapblock_texture_animation (Desynchronize block animation) bool tr
 #    Useful if there's something to be displayed right or left of hotbar.
 hud_hotbar_max_width (Maximum hotbar width) float 1.0
 
-#    Modifies the size of the hudbar elements.
+#    Modifies the size of the HUD elements.
 hud_scaling (HUD scale factor) float 1.0
 
 #    Enables caching of facedir rotated meshes.
@@ -865,6 +870,10 @@ autoscale_mode (Autoscaling mode) enum disable disable,enable,force
 #    A restart is required after changing this.
 show_entity_selectionbox (Show entity selection boxes) bool false
 
+#    Distance in nodes at which transparency depth sorting is enabled
+#    Use this to limit the performance impact of transparency depth sorting
+transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
+
 [*Menus]
 
 #    Use a cloud animation for the main menu background.
@@ -894,10 +903,6 @@ tooltip_show_delay (Tooltip delay) int 400
 #    Append item name to tooltip.
 tooltip_append_itemname (Append item name) bool false
 
-#    Whether FreeType fonts are used, requires FreeType support to be compiled in.
-#    If disabled, bitmap and XML vectors fonts are used instead.
-freetype (FreeType fonts) bool true
-
 font_bold (Font bold by default) bool false
 
 font_italic (Font italic by default) bool false
@@ -908,12 +913,16 @@ font_shadow (Font shadow) int 1
 #    Opaqueness (alpha) of the shadow behind the default font, between 0 and 255.
 font_shadow_alpha (Font shadow alpha) int 127 0 255
 
-#    Font size of the default font in point (pt).
+#    Font size of the default font where 1 unit = 1 pixel at 96 DPI
 font_size (Font size) int 16 1
 
-#    Path to the default font.
-#    If “freetype” setting is enabled: Must be a TrueType font.
-#    If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
+#    For pixel-style fonts that do not scale well, this ensures that font sizes used
+#    with this font will always be divisible by this value, in pixels. For instance,
+#    a pixel font 16 pixels tall should have this set to 16, so it will only ever be
+#    sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32.
+font_size_divisible_by (Font size divisible by) int 1 1
+
+#    Path to the default font. Must be a TrueType font.
 #    The fallback font will be used if the font cannot be loaded.
 font_path (Regular font path) filepath fonts/Arimo-Regular.ttf
 
@@ -921,12 +930,16 @@ font_path_bold (Bold font path) filepath fonts/Arimo-Bold.ttf
 font_path_italic (Italic font path) filepath fonts/Arimo-Italic.ttf
 font_path_bold_italic (Bold and italic font path) filepath fonts/Arimo-BoldItalic.ttf
 
-#    Font size of the monospace font in point (pt).
-mono_font_size (Monospace font size) int 15 1
+#    Font size of the monospace font where 1 unit = 1 pixel at 96 DPI
+mono_font_size (Monospace font size) int 16 1
 
-#    Path to the monospace font.
-#    If “freetype” setting is enabled: Must be a TrueType font.
-#    If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
+#    For pixel-style fonts that do not scale well, this ensures that font sizes used
+#    with this font will always be divisible by this value, in pixels. For instance,
+#    a pixel font 16 pixels tall should have this set to 16, so it will only ever be
+#    sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32.
+mono_font_size_divisible_by (Monospace font size divisible by) int 1 1
+
+#    Path to the monospace font. Must be a TrueType font.
 #    This font is used for e.g. the console and profiler screen.
 mono_font_path (Monospace font path) filepath fonts/Cousine-Regular.ttf
 
@@ -934,9 +947,7 @@ mono_font_path_bold (Bold monospace font path) filepath fonts/Cousine-Bold.ttf
 mono_font_path_italic (Italic monospace font path) filepath fonts/Cousine-Italic.ttf
 mono_font_path_bold_italic (Bold and italic monospace font path) filepath fonts/Cousine-BoldItalic.ttf
 
-#    Path of the fallback font.
-#    If “freetype” setting is enabled: Must be a TrueType font.
-#    If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
+#    Path of the fallback font. Must be a TrueType font.
 #    This font will be used for certain languages or if the default font is unavailable.
 fallback_font_path (Fallback font path) filepath fonts/DroidSansFallbackFull.ttf
 
@@ -949,7 +960,7 @@ chat_font_size (Chat font size) int 0
 screenshot_path (Screenshot folder) path screenshots
 
 #    Format of screenshots.
-screenshot_format (Screenshot format) enum png png,jpg,bmp,pcx,ppm,tga
+screenshot_format (Screenshot format) enum png png,jpg
 
 #    Screenshot quality. Only used for JPEG format.
 #    1 means worst quality; 100 means best quality.
@@ -961,6 +972,9 @@ screenshot_quality (Screenshot quality) int 0 0 100
 #    Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens.
 screen_dpi (DPI) int 72 1
 
+#    Adjust the detected display density, used for scaling UI elements.
+display_density_factor (Display Density Scaling Factor) float 1
+
 #    Windows systems only: Start Minetest with the command line window in the background.
 #    Contains the same information as the file debug.txt (default name).
 enable_console (Enable console window) bool false
@@ -985,8 +999,8 @@ mute_sound (Mute sound) bool false
 
 [Client]
 
-#    Clickable weblinks (middle-click or ctrl-left-click) enabled in chat console output.
-clickable_chat_weblinks (Chat weblinks) bool false
+#    Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output.
+clickable_chat_weblinks (Chat weblinks) bool true
 
 #    Optional override for chat weblink color.
 chat_weblink_color (Weblink color) string
@@ -1044,6 +1058,12 @@ client_unload_unused_data_timeout (Mapblock unload timeout) int 600
 #    Set to -1 for unlimited amount.
 client_mapblock_limit (Mapblock limit) int 7500
 
+#    Whether to show technical names.
+#    Affects mods and texture packs in the Content and Select Mods menus, as well as
+#    setting names in All Settings.
+#    Controlled by the checkbox in the "All settings" menu.
+show_technical_names (Show technical names) bool false
+
 #    Whether to show the client debug info (has the same effect as hitting F5).
 show_debug (Show debug info) bool false
 
@@ -1114,7 +1134,7 @@ max_packets_per_iteration (Max. packets per iteration) int 1024
 
 #    Compression level to use when sending mapblocks to the client.
 #    -1 - use default compression level
-#     0 - least compresson, fastest
+#     0 - least compression, fastest
 #     9 - best compression, slowest
 map_compression_level_net (Map Compression Level for Network Transfer) int -1 -1 9
 
@@ -1178,7 +1198,7 @@ enable_mod_channels (Mod channels) bool false
 #    If this is set, players will always (re)spawn at the given position.
 static_spawnpoint (Static spawnpoint) string
 
-#    If enabled, new players cannot join with an empty password.
+#    If enabled, players cannot join without a password or change theirs to an empty password.
 disallow_empty_password (Disallow empty passwords) bool false
 
 #    If enabled, disable cheat prevention in multiplayer.
@@ -1300,7 +1320,7 @@ movement_gravity (Gravity) float 9.81
 deprecated_lua_api_handling (Deprecated Lua API handling) enum log none,log,error
 
 #    Number of extra blocks that can be loaded by /clearobjects at once.
-#    This is a trade-off between sqlite transaction overhead and
+#    This is a trade-off between SQLite transaction overhead and
 #    memory consumption (4096=100MB, as a rule of thumb).
 max_clearobjects_extra_loaded_blocks (Max. clearobjects extra blocks) int 4096
 
@@ -1309,14 +1329,14 @@ max_clearobjects_extra_loaded_blocks (Max. clearobjects extra blocks) int 4096
 server_unload_unused_data_timeout (Unload unused server data) int 29
 
 #    Maximum number of statically stored objects in a block.
-max_objects_per_block (Maximum objects per block) int 64
+max_objects_per_block (Maximum objects per block) int 256
 
 #    See https://www.sqlite.org/pragma.html#pragma_synchronous
 sqlite_synchronous (Synchronous SQLite) enum 2 0,1,2
 
 #    Compression level to use when saving mapblocks to disk.
 #    -1 - use default compression level
-#     0 - least compresson, fastest
+#     0 - least compression, fastest
 #     9 - best compression, slowest
 map_compression_level_disk (Map Compression Level for Disk Storage) int -1 -1 9
 
@@ -1423,8 +1443,8 @@ instrument.abm (Active Block Modifiers) bool true
 #    Instrument the action function of Loading Block Modifiers on registration.
 instrument.lbm (Loading Block Modifiers) bool true
 
-#    Instrument chatcommands on registration.
-instrument.chatcommand (Chatcommands) bool true
+#    Instrument chat commands on registration.
+instrument.chatcommand (Chat commands) bool true
 
 #    Instrument global callback functions on registration.
 #    (anything you pass to a minetest.register_*() function)
@@ -1460,7 +1480,8 @@ language (Language) enum   ,be,bg,ca,cs,da,de,el,en,eo,es,et,eu,fi,fr,gd,gl,hu,i
 #    -    action
 #    -    info
 #    -    verbose
-debug_log_level (Debug log level) enum action ,none,error,warning,action,info,verbose
+#    -    trace
+debug_log_level (Debug log level) enum action ,none,error,warning,action,info,verbose,trace
 
 #    If the file size of debug.txt exceeds the number of megabytes specified in
 #    this setting when it is opened, the file is moved to debug.txt.1,
@@ -1469,7 +1490,7 @@ debug_log_level (Debug log level) enum action ,none,error,warning,action,info,ve
 debug_log_size_max (Debug log file size threshold) int 50
 
 #    Minimal level of logging to be written to chat.
-chat_log_level (Chat log level) enum error ,none,error,warning,action,info,verbose
+chat_log_level (Chat log level) enum error ,none,error,warning,action,info,verbose,trace
 
 #    Enable IPv6 support (for both client and server).
 #    Required for IPv6 connections to work at all.
@@ -1514,11 +1535,11 @@ max_block_generate_distance (Max block generate distance) int 10
 #    Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).
 #    Only mapchunks completely within the mapgen limit are generated.
 #    Value is stored per-world.
-mapgen_limit (Map generation limit) int 31000 0 31000
+mapgen_limit (Map generation limit) int 31007 0 31007
 
 #    Global map generation attributes.
 #    In Mapgen v6 the 'decorations' flag controls all decorations except trees
-#    and junglegrass, in all other mapgens this flag controls all decorations.
+#    and jungle grass, in all other mapgens this flag controls all decorations.
 mg_flags (Mapgen flags) flags caves,dungeons,light,decorations,biomes,ores caves,dungeons,light,decorations,biomes,ores,nocaves,nodungeons,nolight,nodecorations,nobiomes,noores
 
 [*Biome API temperature and humidity noise parameters]
@@ -2270,7 +2291,7 @@ contentdb_max_concurrent_downloads (ContentDB Max Concurrent Downloads) int 3
 [Cheat Menu]
 
 #   Font to use for cheat menu
-cheat_menu_font (MenuFont) enum FM_Mono FM_Standard,FM_Mono,FM_Fallback,FM_Simple,FM_SimpleMono,FM_MaxMode,FM_Unspecified
+cheat_menu_font (MenuFont) enum FM_Mono FM_Standard,FM_Mono,FM_Fallback,FM_MaxMode,FM_Unspecified
 
 #   (RGB value)
 cheat_menu_bg_color (Cell background color) v3f 255, 145, 88
index 87ef9af7d649d3c16b52ff91a91b58a2b5194062..8110f6fd3dfbc2297ad4908d8ff9d2da9ae9968a 100644 (file)
@@ -1,5 +1,6 @@
 uniform sampler2D baseTexture;
 
+uniform vec3 dayLight;
 uniform vec4 skyBgColor;
 uniform float fogDistance;
 uniform vec3 eyePosition;
@@ -15,10 +16,15 @@ uniform float animationTimer;
        uniform float f_textureresolution;
        uniform mat4 m_ShadowViewProj;
        uniform float f_shadowfar;
-       varying float normalOffsetScale;
+       uniform float f_shadow_strength;
+       uniform vec4 CameraPos;
+       uniform float xyPerspectiveBias0;
+       uniform float xyPerspectiveBias1;
+       
        varying float adj_shadow_strength;
        varying float cosLight;
        varying float f_normal_length;
+       varying vec3 shadow_position;
 #endif
 
 
@@ -42,23 +48,7 @@ varying float nightRatio;
 const float fogStart = FOG_START;
 const float fogShadingParameter = 1.0 / ( 1.0 - fogStart);
 
-
-
 #ifdef ENABLE_DYNAMIC_SHADOWS
-const float bias0 = 0.9;
-const float zPersFactor = 0.5;
-const float bias1 = 1.0 - bias0 + 1e-6;
-
-vec4 getPerspectiveFactor(in vec4 shadowPosition)
-{
-
-       float pDistance = length(shadowPosition.xy);
-       float pFactor = pDistance * bias0 + bias1;
-
-       shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPersFactor);
-
-       return shadowPosition;
-}
 
 // assuming near is always 1.0
 float getLinearDepth()
@@ -68,16 +58,7 @@ float getLinearDepth()
 
 vec3 getLightSpacePosition()
 {
-       vec4 pLightSpace;
-       // some drawtypes have zero normals, so we need to handle it :(
-       #if DRAW_TYPE == NDT_PLANTLIKE
-       pLightSpace = m_ShadowViewProj * vec4(worldPosition, 1.0);
-       #else
-       float offsetScale = (0.0057 * getLinearDepth() + normalOffsetScale);
-       pLightSpace = m_ShadowViewProj * vec4(worldPosition + offsetScale * normalize(vNormal), 1.0);
-       #endif
-       pLightSpace = getPerspectiveFactor(pLightSpace);
-       return pLightSpace.xyz * 0.5 + 0.5;
+       return shadow_position * 0.5 + 0.5;
 }
 // custom smoothstep implementation because it's not defined in glsl1.2
 // https://docs.gl/sl4/smoothstep
@@ -170,13 +151,13 @@ float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDis
 
 float getBaseLength(vec2 smTexCoord)
 {
-       float l = length(2.0 * smTexCoord.xy - 1.0);     // length in texture coords
-       return bias1 / (1.0 / l - bias0);                                // return to undistorted coords
+       float l = length(2.0 * smTexCoord.xy - 1.0 - CameraPos.xy);     // length in texture coords
+       return xyPerspectiveBias1 / (1.0 / l - xyPerspectiveBias0);                              // return to undistorted coords
 }
 
 float getDeltaPerspectiveFactor(float l)
 {
-       return 0.1 / (bias0 * l + bias1);                      // original distortion factor, divided by 10
+       return 0.04 * pow(512.0 / f_textureresolution, 0.4) / (xyPerspectiveBias0 * l + xyPerspectiveBias1);                      // original distortion factor, divided by 10
 }
 
 float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance, float multiplier)
@@ -185,6 +166,9 @@ float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDist
        float perspectiveFactor;
 
        // Return fast if sharp shadows are requested
+       if (PCFBOUND == 0.0)
+               return 0.0;
+
        if (SOFTSHADOWRADIUS <= 1.0) {
                perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
                return max(2 * length(smTexCoord.xy) * 2048 / f_textureresolution / pow(perspectiveFactor, 3), SOFTSHADOWRADIUS);
@@ -479,36 +463,59 @@ void main(void)
        vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
 
 #ifdef ENABLE_DYNAMIC_SHADOWS
-       float shadow_int = 0.0;
-       vec3 shadow_color = vec3(0.0, 0.0, 0.0);
-       vec3 posLightSpace = getLightSpacePosition();
+       if (f_shadow_strength > 0.0) {
+               float shadow_int = 0.0;
+               vec3 shadow_color = vec3(0.0, 0.0, 0.0);
+               vec3 posLightSpace = getLightSpacePosition();
 
-       float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
-       float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1,  posLightSpace.z  ),0.0);
+               float distance_rate = (1.0 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 10.0));
+               if (max(abs(posLightSpace.x - 0.5), abs(posLightSpace.y - 0.5)) > 0.5)
+                       distance_rate = 0.0;
+               float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1,  posLightSpace.z),0.0);
+
+               if (distance_rate > 1e-7) {
 
-       if (distance_rate > 1e-7) {
-       
 #ifdef COLORED_SHADOWS
-               vec4 visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
-               shadow_int = visibility.r;
-               shadow_color = visibility.gba;
+                       vec4 visibility;
+                       if (cosLight > 0.0 || f_normal_length < 1e-3)
+                               visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+                       else
+                               visibility = vec4(1.0, 0.0, 0.0, 0.0);
+                       shadow_int = visibility.r;
+                       shadow_color = visibility.gba;
 #else
-               shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+                       if (cosLight > 0.0 || f_normal_length < 1e-3)
+                               shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+                       else
+                               shadow_int = 1.0;
 #endif
-               shadow_int *= distance_rate;
-               shadow_int *= 1.0 - nightRatio;
+                       shadow_int *= distance_rate;
+                       shadow_int = clamp(shadow_int, 0.0, 1.0);
 
+               }
 
-       }
+               // turns out that nightRatio falls off much faster than
+               // actual brightness of artificial light in relation to natual light.
+               // Power ratio was measured on torches in MTG (brightness = 14).
+               float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
+
+               // Apply self-shadowing when light falls at a narrow angle to the surface
+               // Cosine of the cut-off angle.
+               const float self_shadow_cutoff_cosine = 0.035;
+               if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) {
+                       shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
+                       shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
+               }
 
-       if (f_normal_length != 0 && cosLight < 0.035) {
-               shadow_int = max(shadow_int, min(clamp(1.0-nightRatio, 0.0, 1.0), 1 - clamp(cosLight, 0.0, 0.035)/0.035));
-       }
+               shadow_int *= f_adj_shadow_strength;
 
-       shadow_int = 1.0 - (shadow_int * f_adj_shadow_strength);
-       
-       col.rgb = mix(shadow_color,col.rgb,shadow_int)*shadow_int;
-       // col.r = 0.5 * clamp(getPenumbraRadius(ShadowMapSampler, posLightSpace.xy, posLightSpace.z, 1.0) / SOFTSHADOWRADIUS, 0.0, 1.0) + 0.5 * col.r;
+               // calculate fragment color from components:
+               col.rgb =
+                               adjusted_night_ratio * col.rgb + // artificial light
+                               (1.0 - adjusted_night_ratio) * ( // natural light
+                                               col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) +  // filtered texture color
+                                               dayLight * shadow_color * shadow_int);                 // reflected filtered sunlight/moonlight
+       }
 #endif
 
 #if ENABLE_TONE_MAPPING
@@ -528,6 +535,6 @@ void main(void)
                - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
        col = mix(skyBgColor, col, clarity);
        col = vec4(col.rgb, base.a);
-       
+
        gl_FragColor = col;
 }
index d316930b20e665ab6d9f747a7366b1c12bd17290..3ea0faa36d0b2865cb0eaf1b1ac51b6a2f5c15b3 100644 (file)
@@ -32,10 +32,13 @@ centroid varying vec2 varTexCoord;
        uniform float f_shadowfar;
        uniform float f_shadow_strength;
        uniform float f_timeofday;
+       uniform vec4 CameraPos;
+
        varying float cosLight;
        varying float normalOffsetScale;
        varying float adj_shadow_strength;
        varying float f_normal_length;
+       varying vec3 shadow_position;
 #endif
 
 
@@ -45,8 +48,38 @@ varying float nightRatio;
 const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
 const float e = 2.718281828459;
 const float BS = 10.0;
+uniform float xyPerspectiveBias0;
+uniform float xyPerspectiveBias1;
+uniform float zPerspectiveBias;
 
 #ifdef ENABLE_DYNAMIC_SHADOWS
+
+vec4 getRelativePosition(in vec4 position)
+{
+       vec2 l = position.xy - CameraPos.xy;
+       vec2 s = l / abs(l);
+       s = (1.0 - s * CameraPos.xy);
+       l /= s;
+       return vec4(l, s);
+}
+
+float getPerspectiveFactor(in vec4 relativePosition)
+{
+       float pDistance = length(relativePosition.xy);
+       float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
+       return pFactor;
+}
+
+vec4 applyPerspectiveDistortion(in vec4 position)
+{
+       vec4 l = getRelativePosition(position);
+       float pFactor = getPerspectiveFactor(l);
+       l.xy /= pFactor;
+       position.xy = l.xy * l.zw + CameraPos.xy;
+       position.z *= zPerspectiveBias;
+       return position;
+}
+
 // custom smoothstep implementation because it's not defined in glsl1.2
 // https://docs.gl/sl4/smoothstep
 float mtsmoothstep(in float edge0, in float edge1, in float x)
@@ -193,24 +226,45 @@ void main(void)
        varColor = clamp(color, 0.0, 1.0);
 
 #ifdef ENABLE_DYNAMIC_SHADOWS
-       vec3 nNormal = normalize(vNormal);
-       cosLight = dot(nNormal, -v_LightDirection);
-       float texelSize = 767.0 / f_textureresolution;
-       float slopeScale = clamp(1.0 - abs(cosLight), 0.0, 1.0);
-       normalOffsetScale = texelSize * slopeScale;
-       
-       if (f_timeofday < 0.2) {
-               adj_shadow_strength = f_shadow_strength * 0.5 *
-                       (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
-       } else if (f_timeofday >= 0.8) {
-               adj_shadow_strength = f_shadow_strength * 0.5 *
-                       mtsmoothstep(0.8, 0.83, f_timeofday);
-       } else {
-               adj_shadow_strength = f_shadow_strength *
-                       mtsmoothstep(0.20, 0.25, f_timeofday) *
-                       (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
+       if (f_shadow_strength > 0.0) {
+               vec3 nNormal;
+               f_normal_length = length(vNormal);
+
+               /* normalOffsetScale is in world coordinates (1/10th of a meter)
+                  z_bias is in light space coordinates */
+               float normalOffsetScale, z_bias;
+               float pFactor = getPerspectiveFactor(getRelativePosition(m_ShadowViewProj * mWorld * inVertexPosition));
+               if (f_normal_length > 0.0) {
+                       nNormal = normalize(vNormal);
+                       cosLight = dot(nNormal, -v_LightDirection);
+                       float sinLight = pow(1 - pow(cosLight, 2.0), 0.5);
+                       normalOffsetScale = 2.0 * pFactor * pFactor * sinLight * min(f_shadowfar, 500.0) / 
+                                       xyPerspectiveBias1 / f_textureresolution;
+                       z_bias = 1.0 * sinLight / cosLight;
+               }
+               else {
+                       nNormal = vec3(0.0);
+                       cosLight = clamp(dot(v_LightDirection, normalize(vec3(v_LightDirection.x, 0.0, v_LightDirection.z))), 1e-2, 1.0);
+                       float sinLight = pow(1 - pow(cosLight, 2.0), 0.5);
+                       normalOffsetScale = 0.0;
+                       z_bias = 3.6e3 * sinLight / cosLight;
+               }
+               z_bias *= pFactor * pFactor / f_textureresolution / f_shadowfar;
+
+               shadow_position = applyPerspectiveDistortion(m_ShadowViewProj * mWorld * (inVertexPosition + vec4(normalOffsetScale * nNormal, 0.0))).xyz;
+               shadow_position.z -= z_bias;
+
+               if (f_timeofday < 0.2) {
+                       adj_shadow_strength = f_shadow_strength * 0.5 *
+                               (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
+               } else if (f_timeofday >= 0.8) {
+                       adj_shadow_strength = f_shadow_strength * 0.5 *
+                               mtsmoothstep(0.8, 0.83, f_timeofday);
+               } else {
+                       adj_shadow_strength = f_shadow_strength *
+                               mtsmoothstep(0.20, 0.25, f_timeofday) *
+                               (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
+               }
        }
-       f_normal_length = length(vNormal);
 #endif
-
 }
index 9a0b90f158a74406e1f389f3814c7fe7cf32e309..7baf5826ffaa3ab4126b931de6a263fe89c2528d 100644 (file)
@@ -1,28 +1,14 @@
 uniform sampler2D baseTexture;
 
 uniform vec4 emissiveColor;
+uniform vec3 dayLight;
 uniform vec4 skyBgColor;
 uniform float fogDistance;
 uniform vec3 eyePosition;
 
-varying vec3 vNormal;
-varying vec3 vPosition;
-varying vec3 worldPosition;
-varying lowp vec4 varColor;
-#ifdef GL_ES
-varying mediump vec2 varTexCoord;
-#else
-centroid varying vec2 varTexCoord;
-#endif
-
-varying vec3 eyeVec;
-varying float vIDiff;
-
-const float e = 2.718281828459;
-const float BS = 10.0;
-const float fogStart = FOG_START;
-const float fogShadingParameter = 1.0 / (1.0 - fogStart);
-
+// The cameraOffset is the current center of the visible world.
+uniform vec3 cameraOffset;
+uniform float animationTimer;
 #ifdef ENABLE_DYNAMIC_SHADOWS
        // shadow texture
        uniform sampler2D ShadowMapSampler;
@@ -31,57 +17,41 @@ const float fogShadingParameter = 1.0 / (1.0 - fogStart);
        uniform float f_textureresolution;
        uniform mat4 m_ShadowViewProj;
        uniform float f_shadowfar;
-       uniform float f_timeofday;
-       varying float normalOffsetScale;
+       uniform float f_shadow_strength;
+       uniform vec4 CameraPos;
+       uniform float xyPerspectiveBias0;
+       uniform float xyPerspectiveBias1;
+       
        varying float adj_shadow_strength;
        varying float cosLight;
        varying float f_normal_length;
+       varying vec3 shadow_position;
 #endif
 
-#if ENABLE_TONE_MAPPING
-/* Hable's UC2 Tone mapping parameters
-       A = 0.22;
-       B = 0.30;
-       C = 0.10;
-       D = 0.20;
-       E = 0.01;
-       F = 0.30;
-       W = 11.2;
-       equation used:  ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
-*/
-
-vec3 uncharted2Tonemap(vec3 x)
-{
-       return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
-}
 
-vec4 applyToneMapping(vec4 color)
-{
-       color = vec4(pow(color.rgb, vec3(2.2)), color.a);
-       const float gamma = 1.6;
-       const float exposureBias = 5.5;
-       color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
-       // Precalculated white_scale from
-       //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
-       vec3 whiteScale = vec3(1.036015346);
-       color.rgb *= whiteScale;
-       return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
-}
+varying vec3 vNormal;
+varying vec3 vPosition;
+// World position in the visible world (i.e. relative to the cameraOffset.)
+// This can be used for many shader effects without loss of precision.
+// If the absolute position is required it can be calculated with
+// cameraOffset + worldPosition (for large coordinates the limits of float
+// precision must be considered).
+varying vec3 worldPosition;
+varying lowp vec4 varColor;
+#ifdef GL_ES
+varying mediump vec2 varTexCoord;
+#else
+centroid varying vec2 varTexCoord;
 #endif
+varying vec3 eyeVec;
+varying float nightRatio;
 
-#ifdef ENABLE_DYNAMIC_SHADOWS
-const float bias0 = 0.9;
-const float zPersFactor = 0.5;
-const float bias1 = 1.0 - bias0;
+varying float vIDiff;
 
-vec4 getPerspectiveFactor(in vec4 shadowPosition)
-{
-       float pDistance = length(shadowPosition.xy);
-       float pFactor = pDistance * bias0 + bias1;
-       shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPersFactor);
+const float fogStart = FOG_START;
+const float fogShadingParameter = 1.0 / (1.0 - fogStart);
 
-       return shadowPosition;
-}
+#ifdef ENABLE_DYNAMIC_SHADOWS
 
 // assuming near is always 1.0
 float getLinearDepth()
@@ -91,11 +61,14 @@ float getLinearDepth()
 
 vec3 getLightSpacePosition()
 {
-       vec4 pLightSpace;
-       float normalBias = 0.0005 * getLinearDepth() * cosLight + normalOffsetScale;
-       pLightSpace = m_ShadowViewProj * vec4(worldPosition + normalBias * normalize(vNormal), 1.0);
-       pLightSpace = getPerspectiveFactor(pLightSpace);
-       return pLightSpace.xyz * 0.5 + 0.5;
+       return shadow_position * 0.5 + 0.5;
+}
+// custom smoothstep implementation because it's not defined in glsl1.2
+// https://docs.gl/sl4/smoothstep
+float mtsmoothstep(in float edge0, in float edge1, in float x)
+{
+       float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
+       return t * t * (3.0 - 2.0 * t);
 }
 
 #ifdef COLORED_SHADOWS
@@ -124,10 +97,10 @@ vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDist
 {
        vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy).rgba;
 
-       float visibility = step(0.0, (realDistance-2e-5) - texDepth.r);
+       float visibility = step(0.0, realDistance - texDepth.r);
        vec4 result = vec4(visibility, vec3(0.0,0.0,0.0));//unpackColor(texDepth.g));
        if (visibility < 0.1) {
-               visibility = step(0.0, (realDistance-2e-5) - texDepth.r);
+               visibility = step(0.0, realDistance - texDepth.b);
                result = vec4(visibility, unpackColor(texDepth.a));
        }
        return result;
@@ -138,13 +111,13 @@ vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDist
 float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
 {
        float texDepth = texture2D(shadowsampler, smTexCoord.xy).r;
-       float visibility = step(0.0, (realDistance-2e-5) - texDepth);
-
+       float visibility = step(0.0, realDistance - texDepth);
        return visibility;
 }
 
 #endif
 
+
 #if SHADOW_FILTER == 2
        #define PCFBOUND 3.5
        #define PCFSAMPLES 64.0
@@ -163,6 +136,76 @@ float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance
                #define PCFSAMPLES 1.0
        #endif
 #endif
+#ifdef COLORED_SHADOWS
+float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
+{
+       vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy);
+       float depth = max(realDistance - texDepth.r, realDistance - texDepth.b);
+       return depth;
+}
+#else
+float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
+{
+       float texDepth = texture2D(shadowsampler, smTexCoord.xy).r;
+       float depth = realDistance - texDepth;
+       return depth;
+}
+#endif
+
+float getBaseLength(vec2 smTexCoord)
+{
+       float l = length(2.0 * smTexCoord.xy - 1.0 - CameraPos.xy);     // length in texture coords
+       return xyPerspectiveBias1 / (1.0 / l - xyPerspectiveBias0);                              // return to undistorted coords
+}
+
+float getDeltaPerspectiveFactor(float l)
+{
+       return 0.04 * pow(512.0 / f_textureresolution, 0.4) / (xyPerspectiveBias0 * l + xyPerspectiveBias1);                      // original distortion factor, divided by 10
+}
+
+float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance, float multiplier)
+{
+       float baseLength = getBaseLength(smTexCoord);
+       float perspectiveFactor;
+
+       // Return fast if sharp shadows are requested
+       if (PCFBOUND == 0.0)
+               return 0.0;
+
+       if (SOFTSHADOWRADIUS <= 1.0) {
+               perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
+               return max(2 * length(smTexCoord.xy) * 2048 / f_textureresolution / pow(perspectiveFactor, 3), SOFTSHADOWRADIUS);
+       }
+
+       vec2 clampedpos;
+       float texture_size = 1.0 / (2048 /*f_textureresolution*/ * 0.5);
+       float y, x;
+       float depth = 0.0;
+       float pointDepth;
+       float maxRadius = SOFTSHADOWRADIUS * 5.0 * multiplier;
+
+       float bound = clamp(PCFBOUND * (1 - baseLength), 0.0, PCFBOUND);
+       int n = 0;
+
+       for (y = -bound; y <= bound; y += 1.0)
+       for (x = -bound; x <= bound; x += 1.0) {
+               clampedpos = vec2(x,y);
+               perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * maxRadius);
+               clampedpos = clampedpos * texture_size * perspectiveFactor * maxRadius * perspectiveFactor + smTexCoord.xy;
+
+               pointDepth = getHardShadowDepth(shadowsampler, clampedpos.xy, realDistance);
+               if (pointDepth > -0.01) {
+                       depth += pointDepth;
+                       n += 1;
+               }
+       }
+
+       depth = depth / n;
+       depth = pow(clamp(depth, 0.0, 1000.0), 1.6) / 0.001;
+
+       perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
+       return max(length(smTexCoord.xy) * 2 * 2048 / f_textureresolution / pow(perspectiveFactor, 3), depth * maxRadius);
+}
 
 #ifdef POISSON_FILTER
 const vec2[64] poissonDisk = vec2[64](
@@ -238,17 +281,28 @@ vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance
 {
        vec2 clampedpos;
        vec4 visibility = vec4(0.0);
+       float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.5); // scale to align with PCF
+       if (radius < 0.1) {
+               // we are in the middle of even brightness, no need for filtering
+               return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance);
+       }
+
+       float baseLength = getBaseLength(smTexCoord);
+       float perspectiveFactor;
 
        float texture_size = 1.0 / (f_textureresolution * 0.5);
-       int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-PCFSAMPLES)));
-       int end_offset = int(PCFSAMPLES) + init_offset;
+       int samples = int(clamp(PCFSAMPLES * (1 - baseLength) * (1 - baseLength), PCFSAMPLES / 4, PCFSAMPLES));
+       int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples)));
+       int end_offset = int(samples) + init_offset;
 
        for (int x = init_offset; x < end_offset; x++) {
-               clampedpos = poissonDisk[x] * texture_size * SOFTSHADOWRADIUS + smTexCoord.xy;
+               clampedpos = poissonDisk[x];
+               perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius);
+               clampedpos = clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor + smTexCoord.xy;
                visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance);
        }
 
-       return visibility / PCFSAMPLES;
+       return visibility / samples;
 }
 
 #else
@@ -257,17 +311,28 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
 {
        vec2 clampedpos;
        float visibility = 0.0;
+       float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.5); // scale to align with PCF
+       if (radius < 0.1) {
+               // we are in the middle of even brightness, no need for filtering
+               return getHardShadow(shadowsampler, smTexCoord.xy, realDistance);
+       }
+
+       float baseLength = getBaseLength(smTexCoord);
+       float perspectiveFactor;
 
        float texture_size = 1.0 / (f_textureresolution * 0.5);
-       int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-PCFSAMPLES)));
-       int end_offset = int(PCFSAMPLES) + init_offset;
+       int samples = int(clamp(PCFSAMPLES * (1 - baseLength) * (1 - baseLength), PCFSAMPLES / 4, PCFSAMPLES));
+       int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples)));
+       int end_offset = int(samples) + init_offset;
 
        for (int x = init_offset; x < end_offset; x++) {
-               clampedpos = poissonDisk[x] * texture_size * SOFTSHADOWRADIUS + smTexCoord.xy;
+               clampedpos = poissonDisk[x];
+               perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius);
+               clampedpos = clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor + smTexCoord.xy;
                visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance);
        }
 
-       return visibility / PCFSAMPLES;
+       return visibility / samples;
 }
 
 #endif
@@ -281,19 +346,31 @@ vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance
 {
        vec2 clampedpos;
        vec4 visibility = vec4(0.0);
-       float sradius=0.0;
-       if( PCFBOUND>0)
-               sradius = SOFTSHADOWRADIUS / PCFBOUND;  
+       float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.0);
+       if (radius < 0.1) {
+               // we are in the middle of even brightness, no need for filtering
+               return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance);
+       }
+
+       float baseLength = getBaseLength(smTexCoord);
+       float perspectiveFactor;
+
        float texture_size = 1.0 / (f_textureresolution * 0.5);
        float y, x;
+       float bound = clamp(PCFBOUND * (1 - baseLength), PCFBOUND / 2, PCFBOUND);
+       int n = 0;
+
        // basic PCF filter
-       for (y = -PCFBOUND; y <= PCFBOUND; y += 1.0)
-       for (x = -PCFBOUND; x <= PCFBOUND; x += 1.0) {
-               clampedpos = vec2(x,y) * texture_size* sradius +  smTexCoord.xy;
+       for (y = -bound; y <= bound; y += 1.0)
+       for (x = -bound; x <= bound; x += 1.0) {
+               clampedpos = vec2(x,y);     // screen offset
+               perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius / bound);
+               clampedpos =  clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor / bound + smTexCoord.xy; // both dx,dy and radius are adjusted
                visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance);
+               n += 1;
        }
 
-       return visibility / PCFSAMPLES;
+       return visibility / n;
 }
 
 #else
@@ -301,20 +378,31 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
 {
        vec2 clampedpos;
        float visibility = 0.0;
-       float sradius=0.0;
-       if( PCFBOUND>0)
-               sradius = SOFTSHADOWRADIUS / PCFBOUND;  
-       
+       float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.0);
+       if (radius < 0.1) {
+               // we are in the middle of even brightness, no need for filtering
+               return getHardShadow(shadowsampler, smTexCoord.xy, realDistance);
+       }
+
+       float baseLength = getBaseLength(smTexCoord);
+       float perspectiveFactor;
+
        float texture_size = 1.0 / (f_textureresolution * 0.5);
        float y, x;
+       float bound = clamp(PCFBOUND * (1 - baseLength), PCFBOUND / 2, PCFBOUND);
+       int n = 0;
+
        // basic PCF filter
-       for (y = -PCFBOUND; y <= PCFBOUND; y += 1.0)
-       for (x = -PCFBOUND; x <= PCFBOUND; x += 1.0) {
-               clampedpos =  vec2(x,y) * texture_size * sradius + smTexCoord.xy;
+       for (y = -bound; y <= bound; y += 1.0)
+       for (x = -bound; x <= bound; x += 1.0) {
+               clampedpos = vec2(x,y);     // screen offset
+               perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius / bound);
+               clampedpos =  clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor / bound + smTexCoord.xy; // both dx,dy and radius are adjusted
                visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance);
+               n += 1;
        }
 
-       return visibility / PCFSAMPLES;
+       return visibility / n;
 }
 
 #endif
@@ -322,12 +410,46 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
 #endif
 #endif
 
+#if ENABLE_TONE_MAPPING
+
+/* Hable's UC2 Tone mapping parameters
+       A = 0.22;
+       B = 0.30;
+       C = 0.10;
+       D = 0.20;
+       E = 0.01;
+       F = 0.30;
+       W = 11.2;
+       equation used:  ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
+*/
+
+vec3 uncharted2Tonemap(vec3 x)
+{
+       return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
+}
+
+vec4 applyToneMapping(vec4 color)
+{
+       color = vec4(pow(color.rgb, vec3(2.2)), color.a);
+       const float gamma = 1.6;
+       const float exposureBias = 5.5;
+       color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
+       // Precalculated white_scale from
+       //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
+       vec3 whiteScale = vec3(1.036015346);
+       color.rgb *= whiteScale;
+       return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
+}
+#endif
+
+
+
 void main(void)
 {
        vec3 color;
        vec2 uv = varTexCoord.st;
-       vec4 base = texture2D(baseTexture, uv).rgba;
 
+       vec4 base = texture2D(baseTexture, uv).rgba;
        // If alpha is zero, we can just discard the pixel. This fixes transparency
        // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa,
        // and also on GLES 2, where GL_ALPHA_TEST is missing entirely.
@@ -341,34 +463,66 @@ void main(void)
 #endif
 
        color = base.rgb;
-       vec4 col = vec4(color.rgb, base.a);
-       col.rgb *= varColor.rgb;
-       col.rgb *= emissiveColor.rgb * vIDiff;
+       vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
+       col.rgb *= vIDiff;
 
 #ifdef ENABLE_DYNAMIC_SHADOWS
-       float shadow_int = 0.0;
-       vec3 shadow_color = vec3(0.0, 0.0, 0.0);
-       vec3 posLightSpace = getLightSpacePosition();
+       if (f_shadow_strength > 0.0) {
+               float shadow_int = 0.0;
+               vec3 shadow_color = vec3(0.0, 0.0, 0.0);
+               vec3 posLightSpace = getLightSpacePosition();
+
+               float distance_rate = (1.0 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 10.0));
+               if (max(abs(posLightSpace.x - 0.5), abs(posLightSpace.y - 0.5)) > 0.5)
+                       distance_rate = 0.0;
+               float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1,  posLightSpace.z),0.0);
+
+               if (distance_rate > 1e-7) {
 
 #ifdef COLORED_SHADOWS
-       vec4 visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
-       shadow_int = visibility.r;
-       shadow_color = visibility.gba;
+                       vec4 visibility;
+                       if (cosLight > 0.0 || f_normal_length < 1e-3)
+                               visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+                       else
+                               visibility = vec4(1.0, 0.0, 0.0, 0.0);
+                       shadow_int = visibility.r;
+                       shadow_color = visibility.gba;
 #else
-       shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+                       if (cosLight > 0.0 || f_normal_length < 1e-3)
+                       if (cosLight > 0.0)
+                               shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+                       else
+                               shadow_int = 1.0;
 #endif
-
-       if (f_normal_length != 0 && cosLight <= 0.001) {
-               shadow_int = clamp(shadow_int + 0.5 * abs(cosLight), 0.0, 1.0);
+                       shadow_int *= distance_rate;
+                       shadow_int = clamp(shadow_int, 0.0, 1.0);
+
+               }
+
+               // turns out that nightRatio falls off much faster than
+               // actual brightness of artificial light in relation to natual light.
+               // Power ratio was measured on torches in MTG (brightness = 14).
+               float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
+
+               // Apply self-shadowing when light falls at a narrow angle to the surface
+               // Cosine of the cut-off angle.
+               const float self_shadow_cutoff_cosine = 0.14;
+               if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) {
+                       shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
+                       shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
+               }
+
+               shadow_int *= f_adj_shadow_strength;
+
+               // calculate fragment color from components:
+               col.rgb =
+                               adjusted_night_ratio * col.rgb + // artificial light
+                               (1.0 - adjusted_night_ratio) * ( // natural light
+                                               col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) +  // filtered texture color
+                                               dayLight * shadow_color * shadow_int);                 // reflected filtered sunlight/moonlight
        }
-
-       shadow_int = 1.0 - (shadow_int * adj_shadow_strength);
-
-       col.rgb = mix(shadow_color, col.rgb, shadow_int) * shadow_int;
 #endif
 
-
-
 #if ENABLE_TONE_MAPPING
        col = applyToneMapping(col);
 #endif
@@ -385,6 +539,7 @@ void main(void)
        float clarity = clamp(fogShadingParameter
                - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
        col = mix(skyBgColor, col, clarity);
-
-       gl_FragColor = vec4(col.rgb, base.a);
+       col = vec4(col.rgb, base.a);
+       
+       gl_FragColor = col;
 }
index f135ab9dc6919f42236f1b0b5e06e0afe782f225..6dc25f85481ef86e93e237741ffb88f3858ef2dd 100644 (file)
@@ -1,7 +1,10 @@
 uniform mat4 mWorld;
-
+uniform vec3 dayLight;
 uniform vec3 eyePosition;
 uniform float animationTimer;
+uniform vec4 emissiveColor;
+uniform vec3 cameraOffset;
+
 
 varying vec3 vNormal;
 varying vec3 vPosition;
@@ -21,19 +24,53 @@ centroid varying vec2 varTexCoord;
        uniform float f_shadowfar;
        uniform float f_shadow_strength;
        uniform float f_timeofday;
+       uniform vec4 CameraPos;
+
        varying float cosLight;
-       varying float normalOffsetScale;
        varying float adj_shadow_strength;
        varying float f_normal_length;
+       varying vec3 shadow_position;
 #endif
 
 varying vec3 eyeVec;
+varying float nightRatio;
+// Color of the light emitted by the light sources.
+const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
 varying float vIDiff;
-
 const float e = 2.718281828459;
 const float BS = 10.0;
+uniform float xyPerspectiveBias0;
+uniform float xyPerspectiveBias1;
+uniform float zPerspectiveBias;
 
 #ifdef ENABLE_DYNAMIC_SHADOWS
+
+vec4 getRelativePosition(in vec4 position)
+{
+       vec2 l = position.xy - CameraPos.xy;
+       vec2 s = l / abs(l);
+       s = (1.0 - s * CameraPos.xy);
+       l /= s;
+       return vec4(l, s);
+}
+
+float getPerspectiveFactor(in vec4 relativePosition)
+{
+       float pDistance = length(relativePosition.xy);
+       float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
+       return pFactor;
+}
+
+vec4 applyPerspectiveDistortion(in vec4 position)
+{
+       vec4 l = getRelativePosition(position);
+       float pFactor = getPerspectiveFactor(l);
+       l.xy /= pFactor;
+       position.xy = l.xy * l.zw + CameraPos.xy;
+       position.z *= zPerspectiveBias;
+       return position;
+}
+
 // custom smoothstep implementation because it's not defined in glsl1.2
 // https://docs.gl/sl4/smoothstep
 float mtsmoothstep(in float edge0, in float edge1, in float x)
@@ -60,7 +97,7 @@ void main(void)
        gl_Position = mWorldViewProj * inVertexPosition;
 
        vPosition = gl_Position.xyz;
-       vNormal = inVertexNormal;
+       vNormal = (mWorld * vec4(inVertexNormal, 0.0)).xyz;
        worldPosition = (mWorld * inVertexPosition).xyz;
        eyeVec = -(mWorldView * inVertexPosition).xyz;
 
@@ -75,29 +112,68 @@ void main(void)
 #endif
 
 #ifdef GL_ES
-       varColor = inVertexColor.bgra;
+       vec4 color = inVertexColor.bgra;
 #else
-       varColor = inVertexColor;
+       vec4 color = inVertexColor;
 #endif
 
-#ifdef ENABLE_DYNAMIC_SHADOWS
+       color *= emissiveColor;
 
-       cosLight = max(0.0, dot(vNormal, -v_LightDirection));
-       float texelSize = 0.51;
-       float slopeScale = clamp(1.0 - cosLight, 0.0, 1.0);
-       normalOffsetScale = texelSize * slopeScale;
-       if (f_timeofday < 0.2) {
-               adj_shadow_strength = f_shadow_strength * 0.5 *
-                       (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
-       } else if (f_timeofday >= 0.8) {
-               adj_shadow_strength = f_shadow_strength * 0.5 *
-                       mtsmoothstep(0.8, 0.83, f_timeofday);
-       } else {
-               adj_shadow_strength = f_shadow_strength *
-                       mtsmoothstep(0.20, 0.25, f_timeofday) *
-                       (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
-       }
-       f_normal_length = length(vNormal);
+       // The alpha gives the ratio of sunlight in the incoming light.
+       nightRatio = 1.0 - color.a;
+       color.rgb = color.rgb * (color.a * dayLight.rgb +
+               nightRatio * artificialLight.rgb) * 2.0;
+       color.a = 1.0;
 
+       // Emphase blue a bit in darker places
+       // See C++ implementation in mapblock_mesh.cpp final_color_blend()
+       float brightness = (color.r + color.g + color.b) / 3.0;
+       color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
+               0.07 * brightness);
+
+       varColor = clamp(color, 0.0, 1.0);
+
+
+#ifdef ENABLE_DYNAMIC_SHADOWS
+       if (f_shadow_strength > 0.0) {
+               vec3 nNormal = normalize(vNormal);
+               f_normal_length = length(vNormal);
+
+               /* normalOffsetScale is in world coordinates (1/10th of a meter)
+                  z_bias is in light space coordinates */
+               float normalOffsetScale, z_bias;
+               float pFactor = getPerspectiveFactor(getRelativePosition(m_ShadowViewProj * mWorld * inVertexPosition));
+               if (f_normal_length > 0.0) {
+                       nNormal = normalize(vNormal);
+                       cosLight = dot(nNormal, -v_LightDirection);
+                       float sinLight = pow(1 - pow(cosLight, 2.0), 0.5);
+                       normalOffsetScale = 0.1 * pFactor * pFactor * sinLight * min(f_shadowfar, 500.0) / 
+                                       xyPerspectiveBias1 / f_textureresolution;
+                       z_bias = 1e3 * sinLight / cosLight * (0.5 + f_textureresolution / 1024.0);
+               }
+               else {
+                       nNormal = vec3(0.0);
+                       cosLight = clamp(dot(v_LightDirection, normalize(vec3(v_LightDirection.x, 0.0, v_LightDirection.z))), 1e-2, 1.0);
+                       float sinLight = pow(1 - pow(cosLight, 2.0), 0.5);
+                       normalOffsetScale = 0.0;
+                       z_bias = 3.6e3 * sinLight / cosLight;
+               }
+               z_bias *= pFactor * pFactor / f_textureresolution / f_shadowfar;
+
+               shadow_position = applyPerspectiveDistortion(m_ShadowViewProj * mWorld * (inVertexPosition + vec4(normalOffsetScale * nNormal, 0.0))).xyz;
+               shadow_position.z -= z_bias;
+
+               if (f_timeofday < 0.2) {
+                       adj_shadow_strength = f_shadow_strength * 0.5 *
+                               (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
+               } else if (f_timeofday >= 0.8) {
+                       adj_shadow_strength = f_shadow_strength * 0.5 *
+                               mtsmoothstep(0.8, 0.83, f_timeofday);
+               } else {
+                       adj_shadow_strength = f_shadow_strength *
+                               mtsmoothstep(0.20, 0.25, f_timeofday) *
+                               (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
+               }
+       }
 #endif
 }
index 9f9e5be8cce29c2c69de9310d15506179961a1a8..b267c221480b434fcddabf2eb35ed61bc332e5a2 100644 (file)
@@ -2,6 +2,8 @@ uniform sampler2D ColorMapSampler;
 varying vec4 tPos;
 
 #ifdef COLORED_SHADOWS
+varying vec3 varColor;
+
 // c_precision of 128 fits within 7 base-10 digits
 const float c_precision = 128.0;
 const float c_precisionp1 = c_precision + 1.0;
@@ -30,7 +32,9 @@ void main()
 
        //col.rgb = col.a == 1.0 ? vec3(1.0) : col.rgb;
 #ifdef COLORED_SHADOWS
-       float packedColor = packColor(mix(col.rgb, black, col.a));
+       col.rgb *= varColor.rgb;
+       // premultiply color alpha (see-through side)
+       float packedColor = packColor(col.rgb * (1.0 - col.a));
        gl_FragColor = vec4(depth, packedColor, 0.0,1.0);
 #else
        gl_FragColor = vec4(depth, 0.0, 0.0, 1.0);
index ca59f27966e48aa38776e51ff47c11ca5a1222ea..244d2562aef30e993f05cb3dd2d322ce6ffbed50 100644 (file)
@@ -1,26 +1,50 @@
 uniform mat4 LightMVP; // world matrix
+uniform vec4 CameraPos;
 varying vec4 tPos;
+#ifdef COLORED_SHADOWS
+varying vec3 varColor;
+#endif
 
-const float bias0 = 0.9;
-const float zPersFactor = 0.5;
-const float bias1 = 1.0 - bias0 + 1e-6;
+uniform float xyPerspectiveBias0;
+uniform float xyPerspectiveBias1;
+uniform float zPerspectiveBias;
 
-vec4 getPerspectiveFactor(in vec4 shadowPosition)
+vec4 getRelativePosition(in vec4 position)
 {
-       float pDistance = length(shadowPosition.xy);
-       float pFactor = pDistance * bias0 + bias1;
-       shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPersFactor);
+       vec2 l = position.xy - CameraPos.xy;
+       vec2 s = l / abs(l);
+       s = (1.0 - s * CameraPos.xy);
+       l /= s;
+       return vec4(l, s);
+}
 
-       return shadowPosition;
+float getPerspectiveFactor(in vec4 relativePosition)
+{
+       float pDistance = length(relativePosition.xy);
+       float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
+       return pFactor;
 }
 
+vec4 applyPerspectiveDistortion(in vec4 position)
+{
+       vec4 l = getRelativePosition(position);
+       float pFactor = getPerspectiveFactor(l);
+       l.xy /= pFactor;
+       position.xy = l.xy * l.zw + CameraPos.xy;
+       position.z *= zPerspectiveBias;
+       return position;
+}
 
 void main()
 {
        vec4 pos = LightMVP * gl_Vertex;
 
-       tPos = getPerspectiveFactor(LightMVP * gl_Vertex);
+       tPos = applyPerspectiveDistortion(LightMVP * gl_Vertex);
 
        gl_Position = vec4(tPos.xyz, 1.0);
        gl_TexCoord[0].st = gl_MultiTexCoord0.st;
+
+#ifdef COLORED_SHADOWS
+       varColor = gl_Color.rgb;
+#endif
 }
index a6d8b3db85a7e758250f5bcab7493a64bd1a5035..1dceb93c6b477adcb10fc3a6dad1714221d6802c 100644 (file)
@@ -1,26 +1,43 @@
 uniform mat4 LightMVP; // world matrix
+uniform vec4 CameraPos; // camera position
 varying vec4 tPos;
 
-const float bias0 = 0.9;
-const float zPersFactor = 0.5;
-const float bias1 = 1.0 - bias0 + 1e-6;
+uniform float xyPerspectiveBias0;
+uniform float xyPerspectiveBias1;
+uniform float zPerspectiveBias;
 
-vec4 getPerspectiveFactor(in vec4 shadowPosition)
+vec4 getRelativePosition(in vec4 position)
 {
-       float pDistance = length(shadowPosition.xy);
-       float pFactor = pDistance * bias0 + bias1;
-       shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPersFactor);
+       vec2 l = position.xy - CameraPos.xy;
+       vec2 s = l / abs(l);
+       s = (1.0 - s * CameraPos.xy);
+       l /= s;
+       return vec4(l, s);
+}
 
-       return shadowPosition;
+float getPerspectiveFactor(in vec4 relativePosition)
+{
+       float pDistance = length(relativePosition.xy);
+       float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
+       return pFactor;
 }
 
+vec4 applyPerspectiveDistortion(in vec4 position)
+{
+       vec4 l = getRelativePosition(position);
+       float pFactor = getPerspectiveFactor(l);
+       l.xy /= pFactor;
+       position.xy = l.xy * l.zw + CameraPos.xy;
+       position.z *= zPerspectiveBias;
+       return position;
+}
 
 void main()
 {
        vec4 pos = LightMVP * gl_Vertex;
 
-       tPos = getPerspectiveFactor(pos);
+       tPos = applyPerspectiveDistortion(pos);
 
        gl_Position = vec4(tPos.xyz, 1.0);
-       gl_TexCoord[0].st = gl_MultiTexCoord0.st;
+       gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
 }
index 4e56ec2938fce205e0387676a0e41ca166ce0bd1..23a5c3e90a4b6af247b5fdaa253fbcc0e2ffc29a 100644 (file)
@@ -1 +1 @@
-name = preview 
+name = preview
diff --git a/cmake/Modules/FindOpenGLES2.cmake b/cmake/Modules/FindOpenGLES2.cmake
deleted file mode 100644 (file)
index ce04191..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#-------------------------------------------------------------------
-# The contents of this file are placed in the public domain. Feel
-# free to make use of it in any way you like.
-#-------------------------------------------------------------------
-
-# - Try to find OpenGLES and EGL
-# Once done this will define
-#
-#  OPENGLES2_FOUND        - system has OpenGLES
-#  OPENGLES2_INCLUDE_DIR  - the GL include directory
-#  OPENGLES2_LIBRARIES    - Link these to use OpenGLES
-#
-#  EGL_FOUND        - system has EGL
-#  EGL_INCLUDE_DIR  - the EGL include directory
-#  EGL_LIBRARIES    - Link these to use EGL
-
-# Win32 and Apple are not tested!
-# Linux tested and works
-
-if(WIN32)
-       find_path(OPENGLES2_INCLUDE_DIR GLES2/gl2.h)
-       find_library(OPENGLES2_LIBRARY libGLESv2)
-elseif(APPLE)
-       create_search_paths(/Developer/Platforms)
-       findpkg_framework(OpenGLES2)
-       set(OPENGLES2_LIBRARY "-framework OpenGLES")
-else()
-       # Unix
-       find_path(OPENGLES2_INCLUDE_DIR GLES2/gl2.h
-               PATHS /usr/openwin/share/include
-                       /opt/graphics/OpenGL/include
-                       /usr/X11R6/include
-                       /usr/include
-       )
-
-       find_library(OPENGLES2_LIBRARY
-               NAMES GLESv2
-               PATHS /opt/graphics/OpenGL/lib
-                       /usr/openwin/lib
-                       /usr/X11R6/lib
-                       /usr/lib
-       )
-
-       include(FindPackageHandleStandardArgs)
-       find_package_handle_standard_args(OpenGLES2 DEFAULT_MSG OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR)
-
-       find_path(EGL_INCLUDE_DIR EGL/egl.h
-               PATHS /usr/openwin/share/include
-                       /opt/graphics/OpenGL/include
-                       /usr/X11R6/include
-                       /usr/include
-       )
-
-       find_library(EGL_LIBRARY
-               NAMES EGL
-               PATHS /opt/graphics/OpenGL/lib
-                       /usr/openwin/lib
-                       /usr/X11R6/lib
-                       /usr/lib
-       )
-
-       find_package_handle_standard_args(EGL DEFAULT_MSG EGL_LIBRARY EGL_INCLUDE_DIR)
-endif()
-
-set(OPENGLES2_LIBRARIES ${OPENGLES2_LIBRARY})
-set(EGL_LIBRARIES ${EGL_LIBRARY})
-
-mark_as_advanced(
-       OPENGLES2_INCLUDE_DIR
-       OPENGLES2_LIBRARY
-       EGL_INCLUDE_DIR
-       EGL_LIBRARY
-)
index b23553a807cf7af6634c8b77c4259c8341a67af9..8a66cb241b7cfcf50c12fbe1860e6ba1e415ee7a 100644 (file)
@@ -1,4 +1,4 @@
-mark_as_advanced(SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) 
+mark_as_advanced(SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR)
 
 find_path(SQLITE3_INCLUDE_DIR sqlite3.h)
 
index e5fe7f25e8765fe9388764ccc629556c0044771e..222ddd9d56bd66a27ef174e5e2adacfee4c2a766 100644 (file)
@@ -29,18 +29,17 @@ else(NOT GP2XWIZ)
     find_package_handle_standard_args(Vorbis DEFAULT_MSG
         VORBIS_INCLUDE_DIR VORBIS_LIBRARY)
 endif(NOT GP2XWIZ)
-    
+
 if(VORBIS_FOUND)
-  if(NOT GP2XWIZ)
-     set(VORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY}
-           ${OGG_LIBRARY})
-  else(NOT GP2XWIZ)
-     set(VORBIS_LIBRARIES ${VORBIS_LIBRARY})
-  endif(NOT GP2XWIZ)
+    if(NOT GP2XWIZ)
+        set(VORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY}
+            ${OGG_LIBRARY})
+    else(NOT GP2XWIZ)
+        set(VORBIS_LIBRARIES ${VORBIS_LIBRARY})
+    endif(NOT GP2XWIZ)
 else(VORBIS_FOUND)
-  set(VORBIS_LIBRARIES)
+    set(VORBIS_LIBRARIES)
 endif(VORBIS_FOUND)
 
 mark_as_advanced(OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR)
 mark_as_advanced(OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY)
-
index d7816f0e416d86d6cc9a7c17bb2979762c6bd9af..ae36fd6bf84a1d05fc84df1029c7d2fe47dec935 100644 (file)
@@ -16,7 +16,6 @@ PREDEFINED             = "USE_SPATIAL=1" \
                "USE_REDIS=1" \
                "USE_SOUND=1" \
                "USE_CURL=1" \
-               "USE_FREETYPE=1" \
                "USE_GETTEXT=1"
 
 # Input
diff --git a/doc/breakages.md b/doc/breakages.md
new file mode 100644 (file)
index 0000000..f7078f1
--- /dev/null
@@ -0,0 +1,8 @@
+# Minetest Major Breakages List
+
+This document contains a list of breaking changes to be made in the next major version.
+
+* Remove attachment space multiplier (*10)
+* `get_sky()` returns a table (without arg)
+* `game.conf` name/id mess
+* remove `depends.txt` / `description.txt` (would simplify ContentDB and Minetest code a little)
index 40e0327e4f93664244aab796b17749f39cdadbb7..75e40945ff18517cf0f818e9de69ebb92eea7487 100644 (file)
@@ -1,4 +1,4 @@
-Minetest Lua Client Modding API Reference 5.5.0
+Minetest Lua Client Modding API Reference 5.6.0
 ================================================
 * More information at <http://www.minetest.net/>
 * Developer Wiki: <http://dev.minetest.net/>
@@ -587,6 +587,7 @@ Spatial Vectors
 * `vector.floor(v)`: returns a vector, each dimension rounded down
 * `vector.round(v)`: returns a vector, each dimension rounded to nearest int
 * `vector.apply(v, func)`: returns a vector
+* `vector.combine(v, w, func)`: returns a vector
 * `vector.equals(v1, v2)`: returns a boolean
 
 For the following functions `x` can be either a vector or a number:
@@ -1276,8 +1277,8 @@ Methods:
     * returns true if player is in a liquid (This oscillates so that the player jumps a bit above the surface)
 * `is_in_liquid_stable()`
     * returns true if player is in a stable liquid (This is more stable and defines the maximum speed of the player)
-* `get_liquid_viscosity()`
-    * returns liquid viscosity (Gets the viscosity of liquid to calculate friction)
+* `get_move_resistance()`
+    * returns move resistance of current node, the higher the slower the player moves
 * `is_climbing()`
     * returns true if player is climbing
 * `swimming_vertical()`
@@ -1581,7 +1582,7 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
                liquid_type = <string>,         -- A string containing "none", "flowing", or "source" *May not exist*
                liquid_alternative_flowing = <string>, -- Alternative node for liquid *May not exist*
                liquid_alternative_source = <string>, -- Alternative node for liquid *May not exist*
-               liquid_viscosity = <number>,    -- How fast the liquid flows *May not exist*
+               liquid_viscosity = <number>,    -- How slow the liquid flows *May not exist*
                liquid_renewable = <boolean>,   -- Whether the liquid makes an infinite source *May not exist*
                liquid_range = <number>,        -- How far the liquid flows *May not exist*
                drowning = bool,                -- Whether the player will drown in the node
@@ -1596,6 +1597,7 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
                },
                legacy_facedir_simple = bool,   -- Whether to use old facedir
                legacy_wallmounted = bool       -- Whether to use old wallmounted
+               move_resistance = <number>,     -- How slow players can move through the node *May not exist*
        }
 ```
 
index 4362b49151d7b34ef83b3067a8f9c9f877d72a0e..e5ab03e1238af66de157fae2e6270d7e8f967f93 100644 (file)
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
 that what they have is not the original version, so that the original
 author's reputation will not be affected by problems that might be
 introduced by others.
-\f
+
   Finally, software patents pose a constant threat to the existence of
 any free program.  We wish to make sure that a company cannot
 effectively restrict the users of a free program by obtaining a
@@ -111,7 +111,7 @@ modification follow.  Pay close attention to the difference between a
 "work based on the library" and a "work that uses the library".  The
 former contains code derived from the library, whereas the latter must
 be combined with the library in order to run.
-\f
+
                   GNU LESSER GENERAL PUBLIC LICENSE
    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
@@ -158,7 +158,7 @@ Library.
   You may charge a fee for the physical act of transferring a copy,
 and you may at your option offer warranty protection in exchange for a
 fee.
-\f
+
   2. You may modify your copy or copies of the Library or any portion
 of it, thus forming a work based on the Library, and copy and
 distribute such modifications or work under the terms of Section 1
@@ -216,7 +216,7 @@ instead of to this License.  (If a newer version than version 2 of the
 ordinary GNU General Public License has appeared, then you can specify
 that version instead if you wish.)  Do not make any other change in
 these notices.
-\f
+
   Once this change is made in a given copy, it is irreversible for
 that copy, so the ordinary GNU General Public License applies to all
 subsequent copies and derivative works made from that copy.
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
 distribute the object code for the work under the terms of Section 6.
 Any executables containing that work also fall under Section 6,
 whether or not they are linked directly with the Library itself.
-\f
+
   6. As an exception to the Sections above, you may also combine or
 link a "work that uses the Library" with the Library to produce a
 work containing portions of the Library, and distribute that work
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
 accompany the operating system.  Such a contradiction means you cannot
 use both them and the Library together in an executable that you
 distribute.
-\f
+
   7. You may place library facilities that are a work based on the
 Library side-by-side in a single library together with other library
 facilities not covered by this License, and distribute such a combined
@@ -370,7 +370,7 @@ subject to these terms and conditions.  You may not impose any further
 restrictions on the recipients' exercise of the rights granted herein.
 You are not responsible for enforcing compliance by third parties with
 this License.
-\f
+
   11. If, as a consequence of a court judgment or allegation of patent
 infringement or for any other reason (not limited to patent issues),
 conditions are imposed on you (whether by court order, agreement or
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
 the Free Software Foundation.  If the Library does not specify a
 license version number, you may choose any version ever published by
 the Free Software Foundation.
-\f
+
   14. If you wish to incorporate parts of the Library into other free
 programs whose distribution conditions are incompatible with these,
 write to the author to ask for permission.  For software which is
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 DAMAGES.
 
                      END OF TERMS AND CONDITIONS
-\f
+
            How to Apply These Terms to Your New Libraries
 
   If you develop a new library, and you want it to be of the greatest
index a9bcc170790d06a833664bba9f2e07b156259107..8aea490cfcadf36e927c9ae4e3b8500db3d1351b 100644 (file)
@@ -78,7 +78,7 @@ The game directory can contain the following files:
     * `disallowed_mapgen_settings= <comma-separated mapgen settings>`
       e.g. `disallowed_mapgen_settings = mgv5_spflags`
       These mapgen settings are hidden for this game in the world creation
-      dialog and game start menu.
+      dialog and game start menu. Add `seed` to hide the seed input field.
     * `disabled_settings = <comma-separated settings>`
       e.g. `disabled_settings = enable_damage, creative_mode`
       These settings are hidden for this game in the "Start game" tab
@@ -113,8 +113,16 @@ If you want to specify multiple images for one identifier, add additional
 images named like `$identifier.$n.png`, with an ascending number $n starting
 with 1, and a random image will be chosen from the provided ones.
 
+Menu music
+-----------
 
+Games can provide custom main menu music. They are put inside a `menu`
+directory inside the game directory.
 
+The music files are named `theme.ogg`.
+If you want to specify multiple music files for one game, add additional
+images named like `theme.$n.ogg`, with an ascending number $n starting
+with 1 (max 10), and a random music file will be chosen from the provided ones.
 
 Mods
 ====
@@ -628,6 +636,23 @@ Result is more like what you'd expect if you put a color on top of another
 color, meaning white surfaces get a lot of your new color while black parts
 don't change very much.
 
+#### `[png:<base64>`
+
+Embed a base64 encoded PNG image in the texture string.
+You can produce a valid string for this by calling
+`minetest.encode_base64(minetest.encode_png(tex))`,
+refer to the documentation of these functions for details.
+You can use this to send disposable images such as captchas
+to individual clients, or render things that would be too
+expensive to compose with `[combine:`.
+
+IMPORTANT: Avoid sending large images this way.
+This is not a replacement for asset files, do not use it to do anything
+that you could instead achieve by just using a file.
+In particular consider `minetest.dynamic_add_media` and test whether
+using other texture modifiers could result in a shorter string than
+embedding a whole image, this may vary by use case.
+
 Hardware coloring
 -----------------
 
@@ -1001,7 +1026,7 @@ The function of `param1` is determined by `paramtype` in node definition.
 `param1` is reserved for the engine when `paramtype != "none"`.
 
 * `paramtype = "light"`
-    * The value stores light with and without sun in its upper and lower 4 bits
+    * The value stores light with and without sun in its lower and upper 4 bits
       respectively.
     * Required by a light source node to enable spreading its light.
     * Required by the following drawtypes as they determine their visual
@@ -1519,15 +1544,12 @@ Displays a minimap on the HUD.
 Representations of simple things
 ================================
 
-Position/vector
----------------
-
-    {x=num, y=num, z=num}
+Vector (ie. a position)
+-----------------------
 
-    Note: it is highly recommended to construct a vector using the helper function:
-    vector.new(num, num, num)
+    vector.new(x, y, z)
 
-For helper functions see [Spatial Vectors].
+See [Spatial Vectors] for details.
 
 `pointed_thing`
 ---------------
@@ -1548,8 +1570,7 @@ Exact pointing location (currently only `Raycast` supports these fields):
   from 1).
 * `pointed_thing.intersection_normal`: Unit vector, points outwards of the
   selected selection box. This specifies which face is pointed at.
-  Is a null vector `{x = 0, y = 0, z = 0}` when the pointer is inside the
-  selection box.
+  Is a null vector `vector.zero()` when the pointer is inside the selection box.
 
 
 
@@ -1658,10 +1679,10 @@ wear value. Syntax:
 
 Examples:
 
-* `'default:apple'`: 1 apple
-* `'default:dirt 5'`: 5 dirt
-* `'default:pick_stone'`: a new stone pickaxe
-* `'default:pick_wood 1 21323'`: a wooden pickaxe, ca. 1/3 worn out
+* `"default:apple"`: 1 apple
+* `"default:dirt 5"`: 5 dirt
+* `"default:pick_stone"`: a new stone pickaxe
+* `"default:pick_wood 1 21323"`: a wooden pickaxe, ca. 1/3 worn out
 
 ### Table format
 
@@ -1751,21 +1772,21 @@ Groups in crafting recipes
 An example: Make meat soup from any meat, any water and any bowl:
 
     {
-        output = 'food:meat_soup_raw',
+        output = "food:meat_soup_raw",
         recipe = {
-            {'group:meat'},
-            {'group:water'},
-            {'group:bowl'},
+            {"group:meat"},
+            {"group:water"},
+            {"group:bowl"},
         },
-        -- preserve = {'group:bowl'}, -- Not implemented yet (TODO)
+        -- preserve = {"group:bowl"}, -- Not implemented yet (TODO)
     }
 
 Another example: Make red wool from white wool and red dye:
 
     {
-        type = 'shapeless',
-        output = 'wool:red',
-        recipe = {'wool:white', 'group:dye,basecolor_red'},
+        type = "shapeless",
+        output = "wool:red",
+        recipe = {"wool:white", "group:dye,basecolor_red"},
     }
 
 Special groups
@@ -1804,7 +1825,7 @@ to games.
       - (14)                                           -- constant tolerance
   Negative damage values are discarded as no damage.
 * `falling_node`: if there is no walkable block under the node it will fall
-* `float`: the node will not fall through liquids
+* `float`: the node will not fall through liquids (`liquidtype ~= "none"`)
 * `level`: Can be used to give an additional sense of progression in the game.
      * A larger level will cause e.g. a weapon of a lower level make much less
        damage, and get worn out much faster, or not be able to get drops
@@ -1936,8 +1957,9 @@ to implement this.
 ### Uses (tools only)
 
 Determines how many uses the tool has when it is used for digging a node,
-of this group, of the maximum level. For lower leveled nodes, the use count
-is multiplied by `3^leveldiff`.
+of this group, of the maximum level. The maximum supported number of
+uses is 65535. The special number 0 is used for infinite uses.
+For lower leveled nodes, the use count is multiplied by `3^leveldiff`.
 `leveldiff` is the difference of the tool's `maxlevel` `groupcaps` and the
 node's `level` group. The node cannot be dug if `leveldiff` is less than zero.
 
@@ -2148,6 +2170,13 @@ Some of the values in the key-value store are handled specially:
 * `color`: A `ColorString`, which sets the stack's color.
 * `palette_index`: If the item has a palette, this is used to get the
   current color from the palette.
+* `count_meta`: Replace the displayed count with any string.
+* `count_alignment`: Set the alignment of the displayed count value. This is an
+  int value. The lowest 2 bits specify the alignment in x-direction, the 3rd and
+  4th bit specify the alignment in y-direction:
+  0 = default, 1 = left / up, 2 = middle, 3 = right / down
+  The default currently is the same as right/down.
+  Example: 6 = 2 + 1*4 = middle,up
 
 Example:
 
@@ -2155,6 +2184,21 @@ Example:
     meta:set_string("key", "value")
     print(dump(meta:to_table()))
 
+Example manipulations of "description" and expected output behaviors:
+
+    print(ItemStack("default:pick_steel"):get_description()) --> Steel Pickaxe
+    print(ItemStack("foobar"):get_description()) --> Unknown Item
+
+    local stack = ItemStack("default:stone")
+    stack:get_meta():set_string("description", "Custom description\nAnother line")
+    print(stack:get_description()) --> Custom description\nAnother line
+    print(stack:get_short_description()) --> Custom description
+
+    stack:get_meta():set_string("short_description", "Short")
+    print(stack:get_description()) --> Custom description\nAnother line
+    print(stack:get_short_description()) --> Short
+
+    print(ItemStack("mod:item_with_no_desc"):get_description()) --> mod:item_with_no_desc
 
 
 
@@ -2230,18 +2274,20 @@ Examples
 Version History
 ---------------
 
-* FORMSPEC VERSION 1:
+* Formspec version 1 (pre-5.1.0):
   * (too much)
-* FORMSPEC VERSION 2:
+* Formspec version 2 (5.1.0):
   * Forced real coordinates
   * background9[]: 9-slice scaling parameters
-* FORMSPEC VERSION 3:
+* Formspec version 3 (5.2.0):
   * Formspec elements are drawn in the order of definition
   * bgcolor[]: use 3 parameters (bgcolor, formspec (now an enum), fbgcolor)
   * box[] and image[] elements enable clipping by default
   * new element: scroll_container[]
-* FORMSPEC VERSION 4:
+* Formspec version 4 (5.4.0):
   * Allow dropdown indexing events
+* Formspec version 5 (5.5.0):
+  * Added padding[] element
 
 Elements
 --------
@@ -2285,9 +2331,20 @@ Elements
 * `position` and `anchor` elements need suitable values to avoid a formspec
   extending off the game window due to particular game window sizes.
 
-### `no_prepend[]`
+### `padding[<X>,<Y>]`
 
 * Must be used after the `size`, `position`, and `anchor` elements (if present).
+* Defines how much space is padded around the formspec if the formspec tries to
+  increase past the size of the screen and coordinates have to be shrunk.
+* For X and Y, 0.0 represents no padding (the formspec can touch the edge of the
+  screen), and 0.5 represents half the screen (which forces the coordinate size
+  to 0). If negative, the formspec can extend off the edge of the screen.
+* Defaults to [0.05, 0.05].
+
+### `no_prepend[]`
+
+* Must be used after the `size`, `position`, `anchor`, and `padding` elements
+  (if present).
 * Disables player:set_formspec_prepend() from applying to this formspec.
 
 ### `real_coordinates[<bool>]`
@@ -2334,21 +2391,23 @@ Elements
 * End of a scroll_container, following elements are no longer bound to this
   container.
 
-### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]`
+### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
 
-* Show an inventory list if it has been sent to the client. Nothing will
-  be shown if the inventory list is of size 0.
+* Show an inventory list if it has been sent to the client.
+* If the inventory list changes (eg. it didn't exist before, it's resized, or its items
+  are moved) while the formspec is open, the formspec element may (but is not guaranteed
+  to) adapt to the new inventory list.
+* Item slots are drawn in a grid from left to right, then up to down, ordered
+  according to the slot index.
+* `W` and `H` are in inventory slots, not in coordinates.
+* `starting item index` (Optional): The index of the first (upper-left) item to draw.
+  Indices start at `0`. Default is `0`.
+* The number of shown slots is the minimum of `W*H` and the inventory list's size minus
+  `starting item index`.
 * **Note**: With the new coordinate system, the spacing between inventory
   slots is one-fourth the size of an inventory slot by default. Also see
   [Styling Formspecs] for changing the size of slots and spacing.
 
-### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`
-
-* Show an inventory list if it has been sent to the client. Nothing will
-  be shown if the inventory list is of size 0.
-* **Note**: With the new coordinate system, the spacing between inventory
-  slots is one-fourth the size of an inventory slot.
-
 ### `listring[<inventory location>;<list name>]`
 
 * Allows to create a ring of inventory lists
@@ -3189,7 +3248,7 @@ Colors
 `#RRGGBBAA` defines a color in hexadecimal format and alpha channel.
 
 Named colors are also supported and are equivalent to
-[CSS Color Module Level 4](http://dev.w3.org/csswg/css-color/#named-colors).
+[CSS Color Module Level 4](https://www.w3.org/TR/css-color-4/#named-color).
 To specify the value of the alpha channel, append `#A` or `#AA` to the end of
 the color name (e.g. `colorname#08`).
 
@@ -3242,33 +3301,76 @@ The following functions provide escape sequences:
 
 Spatial Vectors
 ===============
-A spatial vector is similar to a position, but instead using
-absolute world coordinates, it uses *relative* coordinates, relative to
-no particular point.
-
-Internally, it is implemented as a table with the 3 fields
-`x`, `y` and `z`. Example: `{x = 0, y = 1, z = 0}`.
-However, one should *never* create a vector manually as above, such misbehavior
-is deprecated. The vector helpers set a metatable for the created vectors which
-allows indexing with numbers, calling functions directly on vectors and using
-operators (like `+`). Furthermore, the internal implementation might change in
+
+Minetest stores 3-dimensional spatial vectors in Lua as tables of 3 coordinates,
+and has a class to represent them (`vector.*`), which this chapter is about.
+For details on what a spatial vectors is, please refer to Wikipedia:
+https://en.wikipedia.org/wiki/Euclidean_vector.
+
+Spatial vectors are used for various things, including, but not limited to:
+
+* any 3D spatial vector (x/y/z-directions)
+* Euler angles (pitch/yaw/roll in radians) (Spatial vectors have no real semantic
+  meaning here. Therefore, most vector operations make no sense in this use case.)
+
+Note that they are *not* used for:
+
+* n-dimensional vectors where n is not 3 (ie. n=2)
+* arrays of the form `{num, num, num}`
+
+The API documentation may refer to spatial vectors, as produced by `vector.new`,
+by any of the following notations:
+
+* `(x, y, z)` (Used rarely, and only if it's clear that it's a vector.)
+* `vector.new(x, y, z)`
+* `{x=num, y=num, z=num}` (Even here you are still supposed to use `vector.new`.)
+
+Compatibility notes
+-------------------
+
+Vectors used to be defined as tables of the form `{x = num, y = num, z = num}`.
+Since Minetest 5.5.0, vectors additionally have a metatable to enable easier use.
+Note: Those old-style vectors can still be found in old mod code. Hence, mod and
+engine APIs still need to be able to cope with them in many places.
+
+Manually constructed tables are deprecated and highly discouraged. This interface
+should be used to ensure seamless compatibility between mods and the Minetest API.
+This is especially important to callback function parameters and functions overwritten
+by mods.
+Also, though not likely, the internal implementation of a vector might change in
 the future.
-Old code might still use vectors without metatables, be aware of this!
+In your own code, or if you define your own API, you can, of course, still use
+other representations of vectors.
+
+Vectors provided by API functions will provide an instance of this class if not
+stated otherwise. Mods should adapt this for convenience reasons.
+
+Special properties of the class
+-------------------------------
+
+Vectors can be indexed with numbers and allow method and operator syntax.
 
 All these forms of addressing a vector `v` are valid:
 `v[1]`, `v[3]`, `v.x`, `v[1] = 42`, `v.y = 13`
+Note: Prefer letter over number indexing for performance and compatibility reasons.
 
 Where `v` is a vector and `foo` stands for any function name, `v:foo(...)` does
 the same as `vector.foo(v, ...)`, apart from deprecated functionality.
 
+`tostring` is defined for vectors, see `vector.to_string`.
+
 The metatable that is used for vectors can be accessed via `vector.metatable`.
 Do not modify it!
 
 All `vector.*` functions allow vectors `{x = X, y = Y, z = Z}` without metatables.
 Returned vectors always have a metatable set.
 
-For the following functions, `v`, `v1`, `v2` are vectors,
-`p1`, `p2` are positions,
+Common functions and methods
+----------------------------
+
+For the following functions (and subchapters),
+`v`, `v1`, `v2` are vectors,
+`p1`, `p2` are position vectors,
 `s` is a scalar (a number),
 vectors are written like this: `(x, y, z)`:
 
@@ -3290,6 +3392,7 @@ vectors are written like this: `(x, y, z)`:
     * `init`: If given starts looking for the vector at this string index.
 * `vector.to_string(v)`:
     * Returns a string of the form `"(x, y, z)"`.
+    *  `tostring(v)` does the same.
 * `vector.direction(p1, p2)`:
     * Returns a vector of length 1 with direction `p1` to `p2`.
     * If `p1` and `p2` are identical, returns `(0, 0, 0)`.
@@ -3308,6 +3411,9 @@ vectors are written like this: `(x, y, z)`:
 * `vector.apply(v, func)`:
     * Returns a vector where the function `func` has been applied to each
       component.
+* `vector.combine(v, w, func)`:
+       * Returns a vector where the function `func` has combined both components of `v` and `w`
+         for each component
 * `vector.equals(v1, v2)`:
     * Returns a boolean, `true` if the vectors are identical.
 * `vector.sort(v1, v2)`:
@@ -3320,7 +3426,7 @@ vectors are written like this: `(x, y, z)`:
     * Returns the cross product of `v1` and `v2`.
 * `vector.offset(v, x, y, z)`:
     * Returns the sum of the vectors `v` and `(x, y, z)`.
-* `vector.check()`:
+* `vector.check(v)`:
     * Returns a boolean value indicating whether `v` is a real vector, eg. created
       by a `vector.*` function.
     * Returns `false` for anything else, including tables like `{x=3,y=1,z=4}`.
@@ -3342,6 +3448,9 @@ For the following functions `x` can be either a vector or a number:
     * Returns a scaled vector.
     * Deprecated: If `s` is a vector: Returns the Schur quotient.
 
+Operators
+---------
+
 Operators can be used if all of the involved vectors have metatables:
 * `v1 == v2`:
     * Returns whether `v1` and `v2` are identical.
@@ -3358,8 +3467,11 @@ Operators can be used if all of the involved vectors have metatables:
 * `v / s`:
     * Returns `v` scaled by `1 / s`.
 
+Rotation-related functions
+--------------------------
+
 For the following functions `a` is an angle in radians and `r` is a rotation
-vector ({x = <pitch>, y = <yaw>, z = <roll>}) where pitch, yaw and roll are
+vector (`{x = <pitch>, y = <yaw>, z = <roll>}`) where pitch, yaw and roll are
 angles in radians.
 
 * `vector.rotate(v, r)`:
@@ -3376,6 +3488,18 @@ angles in radians.
     * If `up` is omitted, the roll of the returned vector defaults to zero.
     * Otherwise `direction` and `up` need to be vectors in a 90 degree angle to each other.
 
+Further helpers
+---------------
+
+There are more helper functions involving vectors, but they are listed elsewhere
+because they only work on specific sorts of vectors or involve things that are not
+vectors.
+
+For example:
+
+* `minetest.hash_node_position` (Only works on node positions.)
+* `minetest.dir_to_wallmounted` (Involves wallmounted param2 values.)
+
 
 
 
@@ -3460,8 +3584,8 @@ Helper functions
 * `minetest.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a
   position.
     * returns the exact position on the surface of a pointed node
-* `minetest.get_dig_params(groups, tool_capabilities)`: Simulates an item
-    that digs a node.
+* `minetest.get_dig_params(groups, tool_capabilities [, wear])`:
+    Simulates an item that digs a node.
     Returns a table with the following fields:
     * `diggable`: `true` if node can be dug, `false` otherwise.
     * `time`: Time it would take to dig the node.
@@ -3470,15 +3594,17 @@ Helper functions
     Parameters:
     * `groups`: Table of the node groups of the node that would be dug
     * `tool_capabilities`: Tool capabilities table of the item
-* `minetest.get_hit_params(groups, tool_capabilities [, time_from_last_punch])`:
+    * `wear`: Amount of wear the tool starts with (default: 0)
+* `minetest.get_hit_params(groups, tool_capabilities [, time_from_last_punch [, wear]])`:
     Simulates an item that punches an object.
     Returns a table with the following fields:
-    * `hp`: How much damage the punch would cause.
+    * `hp`: How much damage the punch would cause (between -65535 and 65535).
     * `wear`: How much wear would be added to the tool (ignored for non-tools).
     Parameters:
     * `groups`: Damage groups of the object
     * `tool_capabilities`: Tool capabilities table of the item
     * `time_from_last_punch`: time in seconds since last punch action
+    * `wear`: Amount of wear the item starts with (default: 0)
 
 
 
@@ -4149,7 +4275,7 @@ differences:
 
 ### Other API functions operating on a VoxelManip
 
-If any VoxelManip contents were set to a liquid node,
+If any VoxelManip contents were set to a liquid node (`liquidtype ~= "none"`),
 `VoxelManip:update_liquids()` must be called for these liquid nodes to begin
 flowing. It is recommended to call this function only after having written all
 buffered data back to the VoxelManip object, save for special situations where
@@ -4571,6 +4697,8 @@ Utilities
           abm_min_max_y = true,
           -- dynamic_add_media supports passing a table with options (5.5.0)
           dynamic_add_media_table = true,
+          -- allows get_sky to return a table instead of separate values (5.6.0)
+          get_sky_as_table = true,
       }
 
 * `minetest.has_feature(arg)`: returns `boolean, missing_features`
@@ -4606,6 +4734,19 @@ Utilities
 * `minetest.mkdir(path)`: returns success.
     * Creates a directory specified by `path`, creating parent directories
       if they don't exist.
+* `minetest.rmdir(path, recursive)`: returns success.
+    * Removes a directory specified by `path`.
+    * If `recursive` is set to `true`, the directory is recursively removed.
+      Otherwise, the directory will only be removed if it is empty.
+    * Returns true on success, false on failure.
+* `minetest.cpdir(source, destination)`: returns success.
+    * Copies a directory specified by `path` to `destination`
+    * Any files in `destination` will be overwritten if they already exist.
+    * Returns true on success, false on failure.
+* `minetest.mvdir(source, destination)`: returns success.
+    * Moves a directory specified by `path` to `destination`.
+    * If the `destination` is a non-empty directory, then the move will fail.
+    * Returns true on success, false on failure.
 * `minetest.get_dir_list(path, [is_dir])`: returns list of entry names
     * is_dir is one of:
         * nil: return all entries,
@@ -4960,8 +5101,8 @@ Call these functions only at load time!
     * You should have joined some channels to receive events.
     * If message comes from a server mod, `sender` field is an empty string.
 * `minetest.register_on_liquid_transformed(function(pos_list, node_list))`
-    * Called after liquid nodes are modified by the engine's liquid transformation
-      process.
+    * Called after liquid nodes (`liquidtype ~= "none"`) are modified by the
+      engine's liquid transformation process.
     * `pos_list` is an array of all modified positions.
     * `node_list` is an array of the old node that was previously at the position
       with the corresponding index in pos_list.
@@ -5303,7 +5444,8 @@ Environment access
     * `pos1`: start of the ray
     * `pos2`: end of the ray
     * `objects`: if false, only nodes will be returned. Default is `true`.
-    * `liquids`: if false, liquid nodes won't be returned. Default is `false`.
+    * `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be
+                 returned. Default is `false`.
 * `minetest.find_path(pos1,pos2,searchdistance,max_jump,max_drop,algorithm)`
     * returns table containing path that can be walked on
     * returns a table of 3D points representing a path from `pos1` to `pos2` or
@@ -5327,7 +5469,7 @@ Environment access
 * `minetest.spawn_tree (pos, {treedef})`
     * spawns L-system tree at given `pos` with definition in `treedef` table
 * `minetest.transforming_liquid_add(pos)`
-    * add node to liquid update queue
+    * add node to liquid flow update queue
 * `minetest.get_node_max_level(pos)`
     * get max available level for leveled node
 * `minetest.get_node_level(pos)`
@@ -5405,7 +5547,7 @@ Inventory
 * `minetest.remove_detached_inventory(name)`
     * Returns a `boolean` indicating whether the removal succeeded.
 * `minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)`:
-  returns left over ItemStack.
+  returns leftover ItemStack or nil to indicate no inventory change
     * See `minetest.item_eat` and `minetest.register_on_item_eat`
 
 Formspec
@@ -5630,6 +5772,68 @@ Timing
 * `job:cancel()`
     * Cancels the job function from being called
 
+Async environment
+-----------------
+
+The engine allows you to submit jobs to be ran in an isolated environment
+concurrently with normal server operation.
+A job consists of a function to be ran in the async environment, any amount of
+arguments (will be serialized) and a callback that will be called with the return
+value of the job function once it is finished.
+
+The async environment does *not* have access to the map, entities, players or any
+globals defined in the 'usual' environment. Consequently, functions like
+`minetest.get_node()` or `minetest.get_player_by_name()` simply do not exist in it.
+
+Arguments and return values passed through this can contain certain userdata
+objects that will be seamlessly copied (not shared) to the async environment.
+This allows you easy interoperability for delegating work to jobs.
+
+* `minetest.handle_async(func, callback, ...)`:
+    * Queue the function `func` to be ran in an async environment.
+      Note that there are multiple persistent workers and any of them may
+      end up running a given job. The engine will scale the amount of
+      worker threads automatically.
+    * When `func` returns the callback is called (in the normal environment)
+      with all of the return values as arguments.
+    * Optional: Variable number of arguments that are passed to `func`
+* `minetest.register_async_dofile(path)`:
+    * Register a path to a Lua file to be imported when an async environment
+      is initialized. You can use this to preload code which you can then call
+      later using `minetest.handle_async()`.
+
+### List of APIs available in an async environment
+
+Classes:
+* `ItemStack`
+* `PerlinNoise`
+* `PerlinNoiseMap`
+* `PseudoRandom`
+* `PcgRandom`
+* `SecureRandom`
+* `VoxelArea`
+* `VoxelManip`
+    * only if transferred into environment; can't read/write to map
+* `Settings`
+
+Class instances that can be transferred between environments:
+* `ItemStack`
+* `PerlinNoise`
+* `PerlinNoiseMap`
+* `VoxelManip`
+
+Functions:
+* Standalone helpers such as logging, filesystem, encoding,
+  hashing or compression APIs
+* `minetest.request_insecure_environment` (same restrictions apply)
+
+Variables:
+* `minetest.settings`
+* `minetest.registered_items`, `registered_nodes`, `registered_tools`,
+  `registered_craftitems` and `registered_aliases`
+    * with all functions and userdata values replaced by `true`, calling any
+      callbacks here is obviously not possible
+
 Server
 ------
 
@@ -5648,6 +5852,8 @@ Server
       a player joined.
     * This function may be overwritten by mods to customize the status message.
 * `minetest.get_server_uptime()`: returns the server uptime in seconds
+* `minetest.get_server_max_lag()`: returns the current maximum lag
+  of the server in seconds or nil if server is not fully loaded yet
 * `minetest.remove_player(name)`: remove player from database (if they are not
   connected).
     * As auth data is not removed, minetest.player_exists will continue to
@@ -5697,6 +5903,10 @@ Bans
 * `minetest.kick_player(name, [reason])`: disconnect a player with an optional
   reason.
     * Returns boolean indicating success (false if player nonexistant)
+* `minetest.disconnect_player(name, [reason])`: disconnect a player with an
+  optional reason, this will not prefix with 'Kicked: ' like kick_player.
+  If no reason is given, it will default to 'Disconnected.'
+    * Returns boolean indicating success (false if player nonexistant)
 
 Particles
 ---------
@@ -5899,11 +6109,11 @@ Misc.
            This is due to the fact that JSON has two distinct array and object
            values.
     * Example: `write_json({10, {a = false}})`,
-      returns `"[10, {\"a\": false}]"`
+      returns `'[10, {"a": false}]'`
 * `minetest.serialize(table)`: returns a string
     * Convert a table containing tables, strings, numbers, booleans and `nil`s
       into string form readable by `minetest.deserialize`
-    * Example: `serialize({foo='bar'})`, returns `'return { ["foo"] = "bar" }'`
+    * Example: `serialize({foo="bar"})`, returns `'return { ["foo"] = "bar" }'`
 * `minetest.deserialize(string[, safe])`: returns a table
     * Convert a string returned by `minetest.serialize` into a table
     * `string` is loaded in an empty sandbox environment.
@@ -5915,7 +6125,7 @@ Misc.
      value of `safe`. It is fine to serialize then deserialize user-provided
      data, but directly providing user input to deserialize is always unsafe.
     * Example: `deserialize('return { ["foo"] = "bar" }')`,
-      returns `{foo='bar'}`
+      returns `{foo="bar"}`
     * Example: `deserialize('print("foo")')`, returns `nil`
       (function call fails), returns
       `error:[string "print("foo")"]:1: attempt to call global 'print' (a nil value)`
@@ -6128,45 +6338,53 @@ Sorted alphabetically.
 `AreaStore`
 -----------
 
-A fast access data structure to store areas, and find areas near a given
-position or area.
-Every area has a `data` string attribute to store additional information.
-You can create an empty `AreaStore` by calling `AreaStore()`, or
-`AreaStore(type_name)`. The mod decides where to save and load AreaStore.
-If you chose the parameter-less constructor, a fast implementation will be
-automatically chosen for you.
+AreaStore is a data structure to calculate intersections of 3D cuboid volumes
+and points. The `data` field (string) may be used to store and retrieve any
+mod-relevant information to the specified area.
+
+Despite its name, mods must take care of persisting AreaStore data. They may
+use the provided load and write functions for this.
+
 
 ### Methods
 
-* `get_area(id, include_borders, include_data)`
+* `AreaStore(type_name)`
+    * Returns a new AreaStore instance
+    * `type_name`: optional, forces the internally used API.
+        * Possible values: `"LibSpatial"` (default).
+        * When other values are specified, or SpatialIndex is not available,
+          the custom Minetest functions are used.
+* `get_area(id, include_corners, include_data)`
     * Returns the area information about the specified ID.
     * Returned values are either of these:
 
             nil  -- Area not found
-            true -- Without `include_borders` and `include_data`
+            true -- Without `include_corners` and `include_data`
             {
-                min = pos, max = pos -- `include_borders == true`
+                min = pos, max = pos -- `include_corners == true`
                 data = string        -- `include_data == true`
             }
 
-* `get_areas_for_pos(pos, include_borders, include_data)`
+* `get_areas_for_pos(pos, include_corners, include_data)`
     * Returns all areas as table, indexed by the area ID.
     * Table values: see `get_area`.
-* `get_areas_in_area(edge1, edge2, accept_overlap, include_borders, include_data)`
-    * Returns all areas that contain all nodes inside the area specified by `edge1`
-      and `edge2` (inclusive).
+* `get_areas_in_area(corner1, corner2, accept_overlap, include_corners, include_data)`
+    * Returns all areas that contain all nodes inside the area specified by`
+      `corner1 and `corner2` (inclusive).
     * `accept_overlap`: if `true`, areas are returned that have nodes in
       common (intersect) with the specified area.
     * Returns the same values as `get_areas_for_pos`.
-* `insert_area(edge1, edge2, data, [id])`: inserts an area into the store.
+* `insert_area(corner1, corner2, data, [id])`: inserts an area into the store.
     * Returns the new area's ID, or nil if the insertion failed.
-    * The (inclusive) positions `edge1` and `edge2` describe the area.
+    * The (inclusive) positions `corner1` and `corner2` describe the area.
     * `data` is a string stored with the area.
     * `id` (optional): will be used as the internal area ID if it is an unique
       number between 0 and 2^32-2.
-* `reserve(count)`: reserves resources for at most `count` many contained
-  areas.
-  Only needed for efficiency, and only some implementations profit.
+* `reserve(count)`
+    * Requires SpatialIndex, no-op function otherwise.
+    * Reserves resources for `count` many contained areas to improve
+      efficiency when working with many area entries. Additional areas can still
+      be inserted afterwards at the usual complexity.
 * `remove_area(id)`: removes the area with the given id from the store, returns
   success.
 * `set_cache_params(params)`: sets params for the included prefiltering cache.
@@ -6204,9 +6422,9 @@ An `InvRef` is a reference to an inventory.
 * `set_width(listname, width)`: set width of list; currently used for crafting
 * `get_stack(listname, i)`: get a copy of stack index `i` in list
 * `set_stack(listname, i, stack)`: copy `stack` to index `i` in list
-* `get_list(listname)`: return full list
+* `get_list(listname)`: return full list (list of `ItemStack`s)
 * `set_list(listname, list)`: set full list (size will not change)
-* `get_lists()`: returns list of inventory lists
+* `get_lists()`: returns table that maps listnames to inventory lists
 * `set_lists(lists)`: sets inventory lists (size will not change)
 * `add_item(listname, stack)`: add item somewhere in list, returns leftover
   `ItemStack`.
@@ -6566,7 +6784,7 @@ object you are working with still exists.
         * Fourth column: subject looking to the right
         * Fifth column:  subject viewed from above
         * Sixth column:  subject viewed from below
-* `get_entity_name()` (**Deprecated**: Will be removed in a future version)
+* `get_entity_name()` (**Deprecated**: Will be removed in a future version, use the field `self.name` instead)
 * `get_luaentity()`
 
 #### Player only (no-op for other objects)
@@ -6627,6 +6845,7 @@ object you are working with still exists.
 * `set_inventory_formspec(formspec)`
     * Redefine player's inventory form
     * Should usually be called in `on_joinplayer`
+    * If `formspec` is `""`, the player's inventory is disabled.
 * `get_inventory_formspec()`: returns a formspec string
 * `set_formspec_prepend(formspec)`:
     * the formspec string will be added to every formspec shown to the user,
@@ -6641,18 +6860,21 @@ object you are working with still exists.
       `aux1`, `sneak`, `dig`, `place`, `LMB`, `RMB`, and `zoom`.
     * The fields `LMB` and `RMB` are equal to `dig` and `place` respectively,
       and exist only to preserve backwards compatibility.
+    * Returns an empty table `{}` if the object is not a player.
 * `get_player_control_bits()`: returns integer with bit packed player pressed
-  keys. Bits:
-    * 0 - up
-    * 1 - down
-    * 2 - left
-    * 3 - right
-    * 4 - jump
-    * 5 - aux1
-    * 6 - sneak
-    * 7 - dig
-    * 8 - place
-    * 9 - zoom
+  keys.
+    * Bits:
+        * 0 - up
+        * 1 - down
+        * 2 - left
+        * 3 - right
+        * 4 - jump
+        * 5 - aux1
+        * 6 - sneak
+        * 7 - dig
+        * 8 - place
+        * 9 - zoom
+    * Returns `0` (no bits set) if the object is not a player.
 * `set_physics_override(override_table)`
     * `override_table` is a table with the following fields:
         * `speed`: multiplier to default walking speed value (default: `1`)
@@ -6675,17 +6897,18 @@ object you are working with still exists.
 * `hud_get(id)`: gets the HUD element definition structure of the specified ID
 * `hud_set_flags(flags)`: sets specified HUD flags of player.
     * `flags`: A table with the following fields set to boolean values
-        * hotbar
-        * healthbar
-        * crosshair
-        * wielditem
-        * breathbar
-        * minimap
-        * minimap_radar
+        * `hotbar`
+        * `healthbar`
+        * `crosshair`
+        * `wielditem`
+        * `breathbar`
+        * `minimap`: Modifies the client's permission to view the minimap.
+          The client may locally elect to not view the minimap.
+        * `minimap_radar`: is only usable when `minimap` is true
+        * `basic_debug`: Allow showing basic debug info that might give a gameplay advantage.
+          This includes map seed, player position, look direction, the pointed node and block bounds.
+          Does not affect players with the `debug` privilege.
     * If a flag equals `nil`, the flag is not modified
-    * `minimap`: Modifies the client's permission to view the minimap.
-      The client may locally elect to not view the minimap.
-    * `minimap_radar` is only usable when `minimap` is true
 * `hud_get_flags()`: returns a table of player HUD flags with boolean values.
     * See `hud_set_flags` for a list of flags that can be toggled.
 * `hud_set_hotbar_itemcount(count)`: sets number of items in builtin hotbar
@@ -6721,43 +6944,46 @@ object you are working with still exists.
 * `set_sky(sky_parameters)`
     * The presence of the function `set_sun`, `set_moon` or `set_stars` indicates
       whether `set_sky` accepts this format. Check the legacy format otherwise.
+    * Passing no arguments resets the sky to its default values.
     * `sky_parameters` is a table with the following optional fields:
         * `base_color`: ColorSpec, changes fog in "skybox" and "plain".
+          (default: `#ffffff`)
         * `type`: Available types:
             * `"regular"`: Uses 0 textures, `base_color` ignored
             * `"skybox"`: Uses 6 textures, `base_color` used as fog.
             * `"plain"`: Uses 0 textures, `base_color` used as both fog and sky.
+            (default: `"regular"`)
         * `textures`: A table containing up to six textures in the following
             order: Y+ (top), Y- (bottom), X- (west), X+ (east), Z+ (north), Z- (south).
         * `clouds`: Boolean for whether clouds appear. (default: `true`)
-        * `sky_color`: A table containing the following values, alpha is ignored:
-            * `day_sky`: ColorSpec, for the top half of the `"regular"`
-              sky during the day. (default: `#61b5f5`)
-            * `day_horizon`: ColorSpec, for the bottom half of the
-              `"regular"` sky during the day. (default: `#90d3f6`)
-            * `dawn_sky`: ColorSpec, for the top half of the `"regular"`
-              sky during dawn/sunset. (default: `#b4bafa`)
+        * `sky_color`: A table used in `"regular"` type only, containing the
+          following values (alpha is ignored):
+            * `day_sky`: ColorSpec, for the top half of the sky during the day.
+              (default: `#61b5f5`)
+            * `day_horizon`: ColorSpec, for the bottom half of the sky during the day.
+              (default: `#90d3f6`)
+            * `dawn_sky`: ColorSpec, for the top half of the sky during dawn/sunset.
+              (default: `#b4bafa`)
               The resulting sky color will be a darkened version of the ColorSpec.
               Warning: The darkening of the ColorSpec is subject to change.
-            * `dawn_horizon`: ColorSpec, for the bottom half of the `"regular"`
-              sky during dawn/sunset. (default: `#bac1f0`)
+            * `dawn_horizon`: ColorSpec, for the bottom half of the sky during dawn/sunset.
+              (default: `#bac1f0`)
               The resulting sky color will be a darkened version of the ColorSpec.
               Warning: The darkening of the ColorSpec is subject to change.
-            * `night_sky`: ColorSpec, for the top half of the `"regular"`
-              sky during the night. (default: `#006bff`)
+            * `night_sky`: ColorSpec, for the top half of the sky during the night.
+              (default: `#006bff`)
               The resulting sky color will be a dark version of the ColorSpec.
               Warning: The darkening of the ColorSpec is subject to change.
-            * `night_horizon`: ColorSpec, for the bottom half of the `"regular"`
-              sky during the night. (default: `#4090ff`)
+            * `night_horizon`: ColorSpec, for the bottom half of the sky during the night.
+              (default: `#4090ff`)
               The resulting sky color will be a dark version of the ColorSpec.
               Warning: The darkening of the ColorSpec is subject to change.
-            * `indoors`: ColorSpec, for when you're either indoors or
-              underground. Only applies to the `"regular"` sky.
+            * `indoors`: ColorSpec, for when you're either indoors or underground.
               (default: `#646464`)
             * `fog_sun_tint`: ColorSpec, changes the fog tinting for the sun
-              at sunrise and sunset.
+              at sunrise and sunset. (default: `#f47d1d`)
             * `fog_moon_tint`: ColorSpec, changes the fog tinting for the moon
-              at sunrise and sunset.
+              at sunrise and sunset. (default: `#7f99cc`)
             * `fog_tint_type`: string, changes which mode the directional fog
                 abides by, `"custom"` uses `sun_tint` and `moon_tint`, while
                 `"default"` uses the classic Minetest sun and moon tinting.
@@ -6771,15 +6997,22 @@ object you are working with still exists.
         * `"plain"`: Uses 0 textures, `bgcolor` used
     * `clouds`: Boolean for whether clouds appear in front of `"skybox"` or
       `"plain"` custom skyboxes (default: `true`)
-* `get_sky()`: returns base_color, type, table of textures, clouds.
-* `get_sky_color()`: returns a table with the `sky_color` parameters as in
-    `set_sky`.
+* `get_sky(as_table)`:
+    * `as_table`: boolean that determines whether the deprecated version of this
+    function is being used.
+        * `true` returns a table containing sky parameters as defined in `set_sky(sky_parameters)`.
+        * Deprecated: `false` or `nil` returns base_color, type, table of textures,
+        clouds.
+* `get_sky_color()`:
+    * Deprecated: Use `get_sky(as_table)` instead.
+    * returns a table with the `sky_color` parameters as in `set_sky`.
 * `set_sun(sun_parameters)`:
+    * Passing no arguments resets the sun to its default values.
     * `sun_parameters` is a table with the following optional fields:
         * `visible`: Boolean for whether the sun is visible.
             (default: `true`)
         * `texture`: A regular texture for the sun. Setting to `""`
-            will re-enable the mesh sun. (default: `"sun.png"`)
+            will re-enable the mesh sun. (default: "sun.png", if it exists)
         * `tonemap`: A 512x1 texture containing the tonemap for the sun
             (default: `"sun_tonemap.png"`)
         * `sunrise`: A regular texture for the sunrise texture.
@@ -6790,17 +7023,21 @@ object you are working with still exists.
 * `get_sun()`: returns a table with the current sun parameters as in
     `set_sun`.
 * `set_moon(moon_parameters)`:
+    * Passing no arguments resets the moon to its default values.
     * `moon_parameters` is a table with the following optional fields:
         * `visible`: Boolean for whether the moon is visible.
             (default: `true`)
         * `texture`: A regular texture for the moon. Setting to `""`
-            will re-enable the mesh moon. (default: `"moon.png"`)
+            will re-enable the mesh moon. (default: `"moon.png"`, if it exists)
+            Note: Relative to the sun, the moon texture is rotated by 180°.
+            You can use the `^[transformR180` texture modifier to achieve the same orientation.
         * `tonemap`: A 512x1 texture containing the tonemap for the moon
             (default: `"moon_tonemap.png"`)
         * `scale`: Float controlling the overall size of the moon (default: `1`)
 * `get_moon()`: returns a table with the current moon parameters as in
     `set_moon`.
 * `set_stars(star_parameters)`:
+    * Passing no arguments resets stars to their default values.
     * `star_parameters` is a table with the following optional fields:
         * `visible`: Boolean for whether the stars are visible.
             (default: `true`)
@@ -6814,6 +7051,7 @@ object you are working with still exists.
 * `get_stars()`: returns a table with the current stars parameters as in
     `set_stars`.
 * `set_clouds(cloud_parameters)`: set cloud parameters
+    * Passing no arguments resets clouds to their default values.
     * `cloud_parameters` is a table with the following optional fields:
         * `density`: from `0` (no clouds) to `1` (full clouds) (default `0.4`)
         * `color`: basic cloud color with alpha channel, ColorSpec
@@ -6848,6 +7086,12 @@ object you are working with still exists.
     * Returns `false` if failed.
     * Resource intensive - use sparsely
     * To get blockpos, integer divide pos by 16
+* `set_lighting(light_definition)`: sets lighting for the player
+    * `light_definition` is a table with the following optional fields:
+      * `shadows` is a table that controls ambient shadows
+        * `intensity` sets the intensity of the shadows from 0 (no shadows, default) to 1 (blackness)
+* `get_lighting()`: returns the current state of lighting for the player.
+    * Result is a table with the same fields as `light_definition` in `set_lighting`.
 
 `PcgRandom`
 -----------
@@ -6980,7 +7224,8 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
 * `pos1`: start of the ray
 * `pos2`: end of the ray
 * `objects`: if false, only nodes will be returned. Default is true.
-* `liquids`: if false, liquid nodes won't be returned. Default is false.
+* `liquids`: if false, liquid nodes (`liquidtype ~= "none"`) won't be
+             returned. Default is false.
 
 ### Methods
 
@@ -7139,6 +7384,7 @@ Player properties need to be saved manually.
         -- "sprite" uses 1 texture.
         -- "upright_sprite" uses 2 textures: {front, back}.
         -- "wielditem" expects 'textures = {itemname}' (see 'visual' above).
+        -- "mesh" requires one texture for each mesh buffer/material (in order)
 
         colors = {},
         -- Number of required colors depends on visual
@@ -7264,7 +7510,7 @@ Used by `minetest.register_entity`.
         -- for more info) by using a '_' prefix
     }
 
-Collision info passed to `on_step`:
+Collision info passed to `on_step` (`moveresult` argument):
 
     {
         touching_ground = boolean,
@@ -7281,6 +7527,8 @@ Collision info passed to `on_step`:
             },
             ...
         }
+        -- `collisions` does not contain data of unloaded mapblock collisions
+        -- or when the velocity changes are negligibly small
     }
 
 ABM (ActiveBlockModifier) definition
@@ -7464,6 +7712,8 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         range = 4.0,
 
         liquids_pointable = false,
+        -- If true, item points to all liquid nodes (`liquidtype ~= "none"`),
+        -- even those for which `pointable = false`
 
         light_source = 0,
         -- When used for nodes: Defines amount of light emitted by node.
@@ -7521,12 +7771,15 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         on_place = function(itemstack, placer, pointed_thing),
         -- When the 'place' key was pressed with the item in hand
         -- and a node was pointed at.
-        -- Shall place item and return the leftover itemstack.
+        -- Shall place item and return the leftover itemstack
+        -- or nil to not modify the inventory.
         -- The placer may be any ObjectRef or nil.
         -- default: minetest.item_place
 
         on_secondary_use = function(itemstack, user, pointed_thing),
         -- Same as on_place but called when not pointing at a node.
+        -- Function must return either nil if inventory shall not be modified,
+        -- or an itemstack to replace the original itemstack.
         -- The user may be any ObjectRef or nil.
         -- default: nil
 
@@ -7538,8 +7791,8 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
         on_use = function(itemstack, user, pointed_thing),
         -- default: nil
         -- When user pressed the 'punch/mine' key with the item in hand.
-        -- Function must return either nil if no item shall be removed from
-        -- inventory, or an itemstack to replace the original itemstack.
+        -- Function must return either nil if inventory shall not be modified,
+        -- or an itemstack to replace the original itemstack.
         -- e.g. itemstack:take_item(); return itemstack
         -- Otherwise, the function is free to do what it wants.
         -- The user may be any ObjectRef or nil.
@@ -7649,14 +7902,21 @@ Used by `minetest.register_node`.
 
         climbable = false,  -- If true, can be climbed on (ladder)
 
+        move_resistance = 0,
+        -- Slows down movement of players through this node (max. 7).
+        -- If this is nil, it will be equal to liquid_viscosity.
+        -- Note: If liquid movement physics apply to the node
+        -- (see `liquid_move_physics`), the movement speed will also be
+        -- affected by the `movement_liquid_*` settings.
+
         buildable_to = false,  -- If true, placed nodes can replace this node
 
         floodable = false,
         -- If true, liquids flow into and replace this node.
         -- Warning: making a liquid node 'floodable' will cause problems.
 
-        liquidtype = "none",  -- specifies liquid physics
-        -- * "none":    no liquid physics
+        liquidtype = "none",  -- specifies liquid flowing physics
+        -- * "none":    no liquid flowing physics
         -- * "source":  spawns flowing liquid nodes at all 4 sides and below;
         --              recommended drawtype: "liquid".
         -- * "flowing": spawned from source, spawns more flowing liquid nodes
@@ -7670,12 +7930,26 @@ Used by `minetest.register_node`.
 
         liquid_alternative_source = "",  -- Source version of flowing liquid
 
-        liquid_viscosity = 0,  -- Higher viscosity = slower flow (max. 7)
+        liquid_viscosity = 0,
+        -- Controls speed at which the liquid spreads/flows (max. 7).
+        -- 0 is fastest, 7 is slowest.
+        -- By default, this also slows down movement of players inside the node
+        -- (can be overridden using `move_resistance`)
 
         liquid_renewable = true,
         -- If true, a new liquid source can be created by placing two or more
         -- sources nearby
 
+        liquid_move_physics = nil, -- specifies movement physics if inside node
+        -- * false: No liquid movement physics apply.
+        -- * true: Enables liquid movement physics. Enables things like
+        --   ability to "swim" up/down, sinking slowly if not moving,
+        --   smoother speed change when falling into, etc. The `movement_liquid_*`
+        --   settings apply.
+        -- * nil: Will be treated as true if `liquidype ~= "none"`
+        --   and as false otherwise.
+        -- Default: nil
+
         leveled = 0,
         -- Only valid for "nodebox" drawtype with 'type = "leveled"'.
         -- Allows defining the nodebox height without using param2.
@@ -7825,7 +8099,7 @@ Used by `minetest.register_node`.
                     items = {"default:sand", "default:desert_sand"},
                 },
                 {
-                    -- Only drop if using an item in the "magicwand" group, or 
+                    -- Only drop if using an item in the "magicwand" group, or
                     -- an item that is in both the "pickaxe" and the "lucky"
                     -- groups.
                     tool_groups = {
@@ -7967,11 +8241,11 @@ Used by `minetest.register_craft`.
 ### Shaped
 
     {
-        output = 'default:pick_stone',
+        output = "default:pick_stone",
         recipe = {
-            {'default:cobble', 'default:cobble', 'default:cobble'},
-            {'', 'default:stick', ''},
-            {'', 'default:stick', ''},  -- Also groups; e.g. 'group:crumbly'
+            {"default:cobble", "default:cobble", "default:cobble"},
+            {"", "default:stick", ""},
+            {"", "default:stick", ""},  -- Also groups; e.g. "group:crumbly"
         },
         replacements = <list of item pairs>,
         -- replacements: replace one input item with another item on crafting
@@ -7982,7 +8256,7 @@ Used by `minetest.register_craft`.
 
     {
         type = "shapeless",
-        output = 'mushrooms:mushroom_stew',
+        output = "mushrooms:mushroom_stew",
         recipe = {
             "mushrooms:bowl",
             "mushrooms:mushroom_brown",
@@ -8753,3 +9027,10 @@ Used by `minetest.register_authentication_handler`.
         -- Returns an iterator (use with `for` loops) for all player names
         -- currently in the auth database
     }
+
+Bit Library
+-----------
+
+Functions: bit.tobit, bit.tohex, bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift, bit.arshift, bit.rol, bit.ror, bit.bswap
+
+See http://bitop.luajit.org/ for advanced information.
index f4dfff2613f77963ce5a773d405066fb865670b2..c2931af310f6a45aec6d43de75577aaf7a214432 100644 (file)
@@ -1,4 +1,4 @@
-Minetest Lua Mainmenu API Reference 5.5.0
+Minetest Lua Mainmenu API Reference 5.6.0
 =========================================
 
 Introduction
@@ -85,7 +85,9 @@ core.get_video_drivers()
 core.get_mapgen_names([include_hidden=false]) -> table of map generator algorithms
     registered in the core (possible in async calls)
 core.get_cache_path() -> path of cache
-core.get_temp_path() -> path of temp folder
+core.get_temp_path([param]) (possible in async calls)
+^ param=true: returns path to a temporary file
+^ otherwise: returns path to the temporary folder
 
 
 HTTP Requests
@@ -219,7 +221,24 @@ Package - content which is downloadable from the content db, may or may not be i
     * returns path to global user data,
       the directory that contains user-provided mods, worlds, games, and texture packs.
 * core.get_modpath() (possible in async calls)
-    * returns path to global modpath
+    * returns path to global modpath in the user path, where mods can be installed
+* core.get_modpaths() (possible in async calls)
+    * returns table of virtual path to global modpaths, where mods have been installed
+      The difference with "core.get_modpath" is that no mods should be installed in these
+      directories by Minetest -- they might be read-only.
+
+      Ex:
+
+      ```
+      {
+          mods = "/home/user/.minetest/mods",
+          share = "/usr/share/minetest/mods",
+
+          -- Custom dirs can be specified by the MINETEST_MOD_DIR env variable
+          ["/path/to/custom/dir"] = "/path/to/custom/dir",
+      }
+      ```
+
 * core.get_clientmodpath() (possible in async calls)
     * returns path to global client-side modpath
 * core.get_gamepath() (possible in async calls)
index bac70fe1a1125dde465f35e6b9b3fa181301cf37..6a3601f80981d78a26003dde93f7f322c3dab83f 100644 (file)
@@ -112,6 +112,10 @@ leveldb, and files.
 Migrate from current players backend to another. Possible values are sqlite3,
 leveldb, postgresql, dummy, and files.
 .TP
+.B \-\-migrate-mod-storage <value>
+Migrate from current mod storage backend to another. Possible values are
+sqlite3, dummy, and files.
+.TP
 .B \-\-terminal
 Display an interactive terminal over ncurses during execution.
 
@@ -119,6 +123,9 @@ Display an interactive terminal over ncurses during execution.
 .TP
 .B MINETEST_SUBGAME_PATH
 Colon delimited list of directories to search for games.
+.TP
+.B MINETEST_MOD_PATH
+Colon delimited list of directories to search for mods.
 
 .SH BUGS
 Please report all bugs at https://github.com/minetest/minetest/issues.
index 8af2cbad691c4e618f1d363913fb7663ab7ae3da..f738032b683116f67b3424f56cdece7f601afd19 100644 (file)
@@ -90,9 +90,10 @@ by texture packs. All existing fallback textures can be found in the directory
 * `minimap_mask_square.png`: mask used for the square minimap
 * `minimap_overlay_round.png`: overlay texture for the round minimap
 * `minimap_overlay_square.png`: overlay texture for the square minimap
-* `no_texture_airlike.png`: fallback inventory image for airlike nodes
 * `object_marker_red.png`: texture for players on the minimap
 * `player_marker.png`: texture for the own player on the square minimap
+* `no_texture_airlike.png`: fallback inventory image for airlike nodes
+* `no_texture.png`: fallback image for unspecified textures
 
 * `player.png`: front texture of the 2D upright sprite player
 * `player_back.png`: back texture of the 2D upright sprite player
index eb1d7f7282b3a5fccaf88dd535d5a660aa82a27a..17923df8e621a71ff5bf77bf37d5b570a7b6fdb8 100644 (file)
@@ -129,9 +129,34 @@ Example content (added indentation and - explanations):
   backend = sqlite3             - which DB backend to use for blocks (sqlite3, dummy, leveldb, redis, postgresql)
   player_backend = sqlite3      - which DB backend to use for player data
   readonly_backend = sqlite3    - optionally readonly seed DB (DB file _must_ be located in "readonly" subfolder)
+  auth_backend = files          - which DB backend to use for authentication data
   server_announce = false       - whether the server is publicly announced or not
   load_mod_<mod> = false        - whether <mod> is to be loaded in this world
-  auth_backend = files          - which DB backend to use for authentication data
+
+For load_mod_<mod>, the possible values are:
+
+* `false` - Do not load the mod.
+* `true` - Load the mod from wherever it is found (may cause conflicts if the same mod appears also in some other place).
+* `mods/modpack/moddir` - Relative path to the mod
+    * Must be one of the following:
+        * `mods/`: mods in the user path's mods folder (ex `/home/user/.minetest/mods`)
+        * `share/`: mods in the share's mods folder (ex: `/usr/share/minetest/mods`)
+        * `/path/to/env`: you can use absolute paths to mods inside folders specified with the `MINETEST_MOD_PATH` env variable.
+    * Other locations and absolute paths are not supported
+    * Note that `moddir` is the directory name, not the mod name specified in mod.conf.
+
+PostgreSQL backend specific settings:
+  pgsql_connection = host=127.0.0.1 port=5432 user=mt_user password=mt_password dbname=minetest
+  pgsql_player_connection = (same parameters as above)
+  pgsql_readonly_connection = (same parameters as above)
+  pgsql_auth_connection = (same parameters as above)
+
+Redis backend specific settings:
+  redis_address = 127.0.0.1  - Redis server address
+  redis_hash = foo           - Database hash
+  redis_port = 6379          - (optional) connection port
+  redis_password = hunter2   - (optional) server password
+
 
 Player File Format
 ===================
@@ -333,6 +358,9 @@ if map format version >= 29:
   - 0xffffffff = invalid/unknown timestamp, nothing should be done with the time
                  difference when loaded
 
+  u8 name_id_mapping_version
+  - Should be zero for map format version 29.
+  
   u16 num_name_id_mappings
   foreach num_name_id_mappings
     u16 id
@@ -434,7 +462,7 @@ if map format version < 29:
     u8[name_len] name
 
 - Node timers
-if map format version == 25:
+if map format version >= 25:
   u8 length of the data of a single timer (always 2+4+4=10)
   u16 num_of_timers
   foreach num_of_timers:
diff --git a/fonts/mono_dejavu_sans_10.xml b/fonts/mono_dejavu_sans_10.xml
deleted file mode 100644 (file)
index 0276ced..0000000
Binary files a/fonts/mono_dejavu_sans_10.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_100.png b/fonts/mono_dejavu_sans_100.png
deleted file mode 100644 (file)
index 45a3125..0000000
Binary files a/fonts/mono_dejavu_sans_100.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_11.xml b/fonts/mono_dejavu_sans_11.xml
deleted file mode 100644 (file)
index f727ed2..0000000
Binary files a/fonts/mono_dejavu_sans_11.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_110.png b/fonts/mono_dejavu_sans_110.png
deleted file mode 100644 (file)
index c90c0e2..0000000
Binary files a/fonts/mono_dejavu_sans_110.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_12.xml b/fonts/mono_dejavu_sans_12.xml
deleted file mode 100644 (file)
index 38f6427..0000000
Binary files a/fonts/mono_dejavu_sans_12.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_120.png b/fonts/mono_dejavu_sans_120.png
deleted file mode 100644 (file)
index 0cebd70..0000000
Binary files a/fonts/mono_dejavu_sans_120.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_14.xml b/fonts/mono_dejavu_sans_14.xml
deleted file mode 100644 (file)
index b90a349..0000000
Binary files a/fonts/mono_dejavu_sans_14.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_140.png b/fonts/mono_dejavu_sans_140.png
deleted file mode 100644 (file)
index a413759..0000000
Binary files a/fonts/mono_dejavu_sans_140.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_16.xml b/fonts/mono_dejavu_sans_16.xml
deleted file mode 100644 (file)
index 3f7d2c2..0000000
Binary files a/fonts/mono_dejavu_sans_16.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_160.png b/fonts/mono_dejavu_sans_160.png
deleted file mode 100644 (file)
index bd8a2f4..0000000
Binary files a/fonts/mono_dejavu_sans_160.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_18.xml b/fonts/mono_dejavu_sans_18.xml
deleted file mode 100644 (file)
index 92865cb..0000000
Binary files a/fonts/mono_dejavu_sans_18.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_180.png b/fonts/mono_dejavu_sans_180.png
deleted file mode 100644 (file)
index a299afc..0000000
Binary files a/fonts/mono_dejavu_sans_180.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_20.xml b/fonts/mono_dejavu_sans_20.xml
deleted file mode 100644 (file)
index acd8c77..0000000
Binary files a/fonts/mono_dejavu_sans_20.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_200.png b/fonts/mono_dejavu_sans_200.png
deleted file mode 100644 (file)
index 68ee626..0000000
Binary files a/fonts/mono_dejavu_sans_200.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_22.xml b/fonts/mono_dejavu_sans_22.xml
deleted file mode 100644 (file)
index eafb4de..0000000
Binary files a/fonts/mono_dejavu_sans_22.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_220.png b/fonts/mono_dejavu_sans_220.png
deleted file mode 100644 (file)
index 042d7e0..0000000
Binary files a/fonts/mono_dejavu_sans_220.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_24.xml b/fonts/mono_dejavu_sans_24.xml
deleted file mode 100644 (file)
index fc8b623..0000000
Binary files a/fonts/mono_dejavu_sans_24.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_240.png b/fonts/mono_dejavu_sans_240.png
deleted file mode 100644 (file)
index d2d68c5..0000000
Binary files a/fonts/mono_dejavu_sans_240.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_26.xml b/fonts/mono_dejavu_sans_26.xml
deleted file mode 100644 (file)
index 829f099..0000000
Binary files a/fonts/mono_dejavu_sans_26.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_260.png b/fonts/mono_dejavu_sans_260.png
deleted file mode 100644 (file)
index 3a8cb6c..0000000
Binary files a/fonts/mono_dejavu_sans_260.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_28.xml b/fonts/mono_dejavu_sans_28.xml
deleted file mode 100644 (file)
index b5b25bd..0000000
Binary files a/fonts/mono_dejavu_sans_28.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_280.png b/fonts/mono_dejavu_sans_280.png
deleted file mode 100644 (file)
index ccf62ba..0000000
Binary files a/fonts/mono_dejavu_sans_280.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_4.xml b/fonts/mono_dejavu_sans_4.xml
deleted file mode 100644 (file)
index cfebb39..0000000
Binary files a/fonts/mono_dejavu_sans_4.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_40.png b/fonts/mono_dejavu_sans_40.png
deleted file mode 100644 (file)
index 24ed693..0000000
Binary files a/fonts/mono_dejavu_sans_40.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_6.xml b/fonts/mono_dejavu_sans_6.xml
deleted file mode 100644 (file)
index d0e1de2..0000000
Binary files a/fonts/mono_dejavu_sans_6.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_60.png b/fonts/mono_dejavu_sans_60.png
deleted file mode 100644 (file)
index 326af99..0000000
Binary files a/fonts/mono_dejavu_sans_60.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_8.xml b/fonts/mono_dejavu_sans_8.xml
deleted file mode 100644 (file)
index c48bf7c..0000000
Binary files a/fonts/mono_dejavu_sans_8.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_80.png b/fonts/mono_dejavu_sans_80.png
deleted file mode 100644 (file)
index 04326db..0000000
Binary files a/fonts/mono_dejavu_sans_80.png and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_9.xml b/fonts/mono_dejavu_sans_9.xml
deleted file mode 100644 (file)
index 74e8410..0000000
Binary files a/fonts/mono_dejavu_sans_9.xml and /dev/null differ
diff --git a/fonts/mono_dejavu_sans_90.png b/fonts/mono_dejavu_sans_90.png
deleted file mode 100644 (file)
index 65ac518..0000000
Binary files a/fonts/mono_dejavu_sans_90.png and /dev/null differ
diff --git a/games/devtest/.luacheckrc b/games/devtest/.luacheckrc
new file mode 100644 (file)
index 0000000..1c7d399
--- /dev/null
@@ -0,0 +1,43 @@
+unused_args = false
+allow_defined_top = true
+max_string_line_length = false
+max_line_length = false
+
+ignore = {
+       "131", -- Unused global variable
+       "211", -- Unused local variable
+       "231", -- Local variable never accessed
+       "311", -- Value assigned to a local variable is unused
+       "412", -- Redefining an argument
+       "421", -- Shadowing a local variable
+       "431", -- Shadowing an upvalue
+       "432", -- Shadowing an upvalue argument
+       "611", -- Line contains only whitespace
+}
+
+read_globals = {
+       "ItemStack",
+       "INIT",
+       "DIR_DELIM",
+       "dump", "dump2",
+       "fgettext", "fgettext_ne",
+       "vector",
+       "VoxelArea",
+       "profiler",
+       "Settings",
+       "check",
+       "PseudoRandom",
+
+       string = {fields = {"split", "trim"}},
+       table  = {fields = {"copy", "getn", "indexof", "insert_all"}},
+       math   = {fields = {"hypot", "round"}},
+}
+
+globals = {
+       "aborted",
+       "minetest",
+       "core",
+       os = { fields = { "tempfolder" } },
+       "_",
+}
+
index bd7480030fe837146d0e33017100f2bdd7f9c4c7..3ec69d39ff68d81d8b09121277d78f0b094aa571 100644 (file)
@@ -16,11 +16,11 @@ Tool types:
 
 Tool materials:
 
-* Dirt: dig nodes of rating 3, one use only
 * Wood: dig nodes of rating 3
 * Stone: dig nodes of rating 3 or 2
 * Steel: dig nodes of rating 3, 2 or 1
 * Mese: dig "everything" instantly
+* n-Uses: can be used n times before breaking
 ]]
 
 -- The hand
@@ -92,20 +92,6 @@ minetest.register_tool("basetools:pick_mese", {
 -- Pickaxes: Dig cracky
 --
 
--- This should break after only 1 use
-minetest.register_tool("basetools:pick_dirt", {
-       description = "Dirt Pickaxe".."\n"..
-               "Digs cracky=3".."\n"..
-               "1 use only",
-       inventory_image = "basetools_dirtpick.png",
-       tool_capabilities = {
-               max_drop_level=0,
-               groupcaps={
-                       cracky={times={[3]=2.00}, uses=1, maxlevel=0}
-               },
-       },
-})
-
 minetest.register_tool("basetools:pick_wood", {
        description = "Wooden Pickaxe".."\n"..
                "Digs cracky=3",
@@ -293,50 +279,135 @@ minetest.register_tool("basetools:sword_wood", {
 })
 minetest.register_tool("basetools:sword_stone", {
        description = "Stone Sword".."\n"..
-               "Damage: fleshy=4",
+               "Damage: fleshy=5",
        inventory_image = "basetools_stonesword.png",
        tool_capabilities = {
                full_punch_interval = 1.0,
                max_drop_level=0,
-               damage_groups = {fleshy=4},
+               damage_groups = {fleshy=5},
        }
 })
 minetest.register_tool("basetools:sword_steel", {
        description = "Steel Sword".."\n"..
-               "Damage: fleshy=6",
+               "Damage: fleshy=10",
        inventory_image = "basetools_steelsword.png",
        tool_capabilities = {
                full_punch_interval = 1.0,
                max_drop_level=1,
-               damage_groups = {fleshy=6},
+               damage_groups = {fleshy=10},
+       }
+})
+minetest.register_tool("basetools:sword_titanium", {
+       description = "Titanium Sword".."\n"..
+               "Damage: fleshy=100",
+       inventory_image = "basetools_titaniumsword.png",
+       tool_capabilities = {
+               full_punch_interval = 1.0,
+               max_drop_level=1,
+               damage_groups = {fleshy=100},
+       }
+})
+minetest.register_tool("basetools:sword_blood", {
+       description = "Blood Sword".."\n"..
+               "Damage: fleshy=1000",
+       inventory_image = "basetools_bloodsword.png",
+       tool_capabilities = {
+               full_punch_interval = 1.0,
+               max_drop_level=1,
+               damage_groups = {fleshy=1000},
+       }
+})
+
+-- Max. damage sword
+minetest.register_tool("basetools:sword_mese", {
+       description = "Mese Sword".."\n"..
+               "Damage: fleshy=32767, fiery=32767, icy=32767".."\n"..
+               "Full Punch Interval: 0.0s",
+       inventory_image = "basetools_mesesword.png",
+       tool_capabilities = {
+               full_punch_interval = 0.0,
+               max_drop_level=1,
+               damage_groups = {fleshy=32767, fiery=32767, icy=32767},
        }
 })
 
 -- Fire/Ice sword: Deal damage to non-fleshy damage groups
 minetest.register_tool("basetools:sword_fire", {
        description = "Fire Sword".."\n"..
-               "Damage: icy=6",
+               "Damage: icy=10",
        inventory_image = "basetools_firesword.png",
        tool_capabilities = {
                full_punch_interval = 1.0,
                max_drop_level=0,
-               damage_groups = {icy=6},
+               damage_groups = {icy=10},
        }
 })
 minetest.register_tool("basetools:sword_ice", {
        description = "Ice Sword".."\n"..
-               "Damage: fiery=6",
+               "Damage: fiery=10",
        inventory_image = "basetools_icesword.png",
        tool_capabilities = {
                full_punch_interval = 1.0,
                max_drop_level=0,
-               damage_groups = {fiery=6},
+               damage_groups = {fiery=10},
+       }
+})
+minetest.register_tool("basetools:sword_elemental", {
+       description = "Elemental Sword".."\n"..
+               "Damage: fiery=10, icy=10",
+       inventory_image = "basetools_elementalsword.png",
+       tool_capabilities = {
+               full_punch_interval = 1.0,
+               max_drop_level=0,
+               damage_groups = {fiery=10, icy=10},
        }
 })
 
+-- Healing weapons: heal HP
+minetest.register_tool("basetools:dagger_heal", {
+       description = "Healing Dagger".."\n"..
+               "Heal: fleshy=1".."\n"..
+               "Full Punch Interval: 0.5s",
+       inventory_image = "basetools_healdagger.png",
+       tool_capabilities = {
+               full_punch_interval = 0.5,
+               damage_groups = {fleshy=-1},
+       }
+})
+minetest.register_tool("basetools:sword_heal", {
+       description = "Healing Sword".."\n"..
+               "Heal: fleshy=10",
+       inventory_image = "basetools_healsword.png",
+       tool_capabilities = {
+               full_punch_interval = 1.0,
+               damage_groups = {fleshy=-10},
+       }
+})
+minetest.register_tool("basetools:sword_heal_super", {
+       description = "Super Healing Sword".."\n"..
+               "Heal: fleshy=32768, fiery=32768, icy=32768",
+       inventory_image = "basetools_superhealsword.png",
+       tool_capabilities = {
+               full_punch_interval = 1.0,
+               damage_groups = {fleshy=-32768, fiery=-32768, icy=-32768},
+       }
+})
+
+
 --
 -- Dagger: Low damage, fast punch interval
 --
+minetest.register_tool("basetools:dagger_wood", {
+       description = "Wooden Dagger".."\n"..
+               "Damage: fleshy=1".."\n"..
+               "Full Punch Interval: 0.5s",
+       inventory_image = "basetools_wooddagger.png",
+       tool_capabilities = {
+               full_punch_interval = 0.5,
+               max_drop_level=0,
+               damage_groups = {fleshy=1},
+       }
+})
 minetest.register_tool("basetools:dagger_steel", {
        description = "Steel Dagger".."\n"..
                "Damage: fleshy=2".."\n"..
@@ -348,3 +419,31 @@ minetest.register_tool("basetools:dagger_steel", {
                damage_groups = {fleshy=2},
        }
 })
+
+-- Test tool uses and punch_attack_uses
+local uses = { 1, 2, 3, 5, 10, 50, 100, 1000, 10000, 65535 }
+for i=1, #uses do
+       local u = uses[i]
+       local color = string.format("#FF00%02X", math.floor(((i-1)/#uses) * 255))
+       minetest.register_tool("basetools:pick_uses_"..string.format("%05d", u), {
+               description = u.."-Uses Pickaxe".."\n"..
+                       "Digs cracky=3",
+               inventory_image = "basetools_usespick.png^[colorize:"..color..":127",
+               tool_capabilities = {
+                       max_drop_level=0,
+                       groupcaps={
+                               cracky={times={[3]=0.1, [2]=0.2, [1]=0.3}, uses=u, maxlevel=0}
+                       },
+               },
+       })
+
+       minetest.register_tool("basetools:sword_uses_"..string.format("%05d", u), {
+               description = u.."-Uses Sword".."\n"..
+                       "Damage: fleshy=1",
+               inventory_image = "basetools_usessword.png^[colorize:"..color..":127",
+               tool_capabilities = {
+                       damage_groups = {fleshy=1},
+                       punch_attack_uses = u,
+               },
+       })
+end
diff --git a/games/devtest/mods/basetools/textures/basetools_bloodsword.png b/games/devtest/mods/basetools/textures/basetools_bloodsword.png
new file mode 100644 (file)
index 0000000..a521ba4
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_bloodsword.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_dirtpick.png b/games/devtest/mods/basetools/textures/basetools_dirtpick.png
deleted file mode 100644 (file)
index 20a021d..0000000
Binary files a/games/devtest/mods/basetools/textures/basetools_dirtpick.png and /dev/null differ
diff --git a/games/devtest/mods/basetools/textures/basetools_elementalsword.png b/games/devtest/mods/basetools/textures/basetools_elementalsword.png
new file mode 100644 (file)
index 0000000..d007217
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_elementalsword.png differ
index ee2809ab7eeb841f086b1ab0c0f6a5304fcf3cca..eca999ba16bc16eff8fed9471c0cf2d431c861b8 100644 (file)
Binary files a/games/devtest/mods/basetools/textures/basetools_firesword.png and b/games/devtest/mods/basetools/textures/basetools_firesword.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_healdagger.png b/games/devtest/mods/basetools/textures/basetools_healdagger.png
new file mode 100644 (file)
index 0000000..3e6eb9c
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_healdagger.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_healsword.png b/games/devtest/mods/basetools/textures/basetools_healsword.png
new file mode 100644 (file)
index 0000000..f93fddf
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_healsword.png differ
index 35ba8214baf33896323502e91c3c79abfeebf271..55a8d609dfa45d5b6be4cd080514fa6c22f0e2c1 100644 (file)
Binary files a/games/devtest/mods/basetools/textures/basetools_icesword.png and b/games/devtest/mods/basetools/textures/basetools_icesword.png differ
index 2b5e12cdb4f28e7cb9e125119129f2cbc84f6da7..2993b475b7f7eb59908975b6b3efde59a310a598 100644 (file)
Binary files a/games/devtest/mods/basetools/textures/basetools_mesepick.png and b/games/devtest/mods/basetools/textures/basetools_mesepick.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_mesesword.png b/games/devtest/mods/basetools/textures/basetools_mesesword.png
new file mode 100644 (file)
index 0000000..bc82769
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_mesesword.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_superhealsword.png b/games/devtest/mods/basetools/textures/basetools_superhealsword.png
new file mode 100644 (file)
index 0000000..4175a09
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_superhealsword.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_titaniumsword.png b/games/devtest/mods/basetools/textures/basetools_titaniumsword.png
new file mode 100644 (file)
index 0000000..55e22c7
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_titaniumsword.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_usespick.png b/games/devtest/mods/basetools/textures/basetools_usespick.png
new file mode 100644 (file)
index 0000000..27850f9
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_usespick.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_usessword.png b/games/devtest/mods/basetools/textures/basetools_usessword.png
new file mode 100644 (file)
index 0000000..0eaf4cf
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_usessword.png differ
diff --git a/games/devtest/mods/basetools/textures/basetools_wooddagger.png b/games/devtest/mods/basetools/textures/basetools_wooddagger.png
new file mode 100644 (file)
index 0000000..6e5ab0f
Binary files /dev/null and b/games/devtest/mods/basetools/textures/basetools_wooddagger.png differ
diff --git a/games/devtest/mods/broken/init.lua b/games/devtest/mods/broken/init.lua
new file mode 100644 (file)
index 0000000..04993ca
--- /dev/null
@@ -0,0 +1,11 @@
+-- Register stuff with empty definitions to test if Minetest fallback options
+-- for these things work properly.
+
+-- The itemstrings are deliberately kept descriptive to keep them easy to
+-- recognize.
+
+minetest.register_node("broken:node_with_empty_definition", {})
+minetest.register_tool("broken:tool_with_empty_definition", {})
+minetest.register_craftitem("broken:craftitem_with_empty_definition", {})
+
+minetest.register_entity("broken:entity_with_empty_definition", {})
diff --git a/games/devtest/mods/broken/mod.conf b/games/devtest/mods/broken/mod.conf
new file mode 100644 (file)
index 0000000..a24378a
--- /dev/null
@@ -0,0 +1,2 @@
+name = broken
+description = Register items and an entity with empty definitions to test fallback
index 306953d503b657c822f6dbebe6a6793a985a9cd1..415e5bd1970e62d6a1529dd060b73e54cf0a4306 100644 (file)
@@ -4,10 +4,19 @@
 local phasearmor = {
        [0]={icy=100},
        [1]={fiery=100},
-       [2]={fleshy=100},
-       [3]={immortal=1},
-       [4]={punch_operable=1},
+       [2]={icy=100, fiery=100},
+       [3]={fleshy=-100},
+       [4]={fleshy=1},
+       [5]={fleshy=10},
+       [6]={fleshy=50},
+       [7]={fleshy=100},
+       [8]={fleshy=200},
+       [9]={fleshy=1000},
+       [10]={fleshy=32767},
+       [11]={immortal=1},
+       [12]={punch_operable=1},
 }
+local max_phase = 12
 
 minetest.register_entity("testentities:armorball", {
        initial_properties = {
@@ -17,11 +26,11 @@ minetest.register_entity("testentities:armorball", {
                visual = "sprite",
                visual_size = {x=1, y=1},
                textures = {"testentities_armorball.png"},
-               spritediv = {x=1, y=5},
+               spritediv = {x=1, y=max_phase+1},
                initial_sprite_basepos = {x=0, y=0},
        },
 
-       _phase = 2,
+       _phase = 7,
 
        on_activate = function(self, staticdata)
                minetest.log("action", "[testentities] armorball.on_activate")
@@ -32,10 +41,21 @@ minetest.register_entity("testentities:armorball", {
        on_rightclick = function(self, clicker)
                -- Change armor group and sprite
                self._phase = self._phase + 1
-               if self._phase >= 5 then
+               if self._phase >= max_phase + 1 then
                        self._phase = 0
                end
                self.object:set_sprite({x=0, y=self._phase})
                self.object:set_armor_groups(phasearmor[self._phase])
        end,
+
+       on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
+               if not puncher then
+                       return
+               end
+               local name = puncher:get_player_name()
+               if not name then
+                       return
+               end
+               minetest.chat_send_player(name, "time_from_last_punch="..string.format("%.3f", time_from_last_punch).."; damage="..tostring(damage))
+       end,
 })
index 88147bd1f77c3cb377158ee2df87f547f0b795f7..708c7b36d88c78f8ef76d90cf2db172c9ddbe46b 100644 (file)
Binary files a/games/devtest/mods/testentities/textures/testentities_armorball.png and b/games/devtest/mods/testentities/textures/testentities_armorball.png differ
index 501b5e35436a9a75d82b343d56fd615f4f919a62..9f867631ff67f13f37103290ce5757229c422fc8 100644 (file)
@@ -270,6 +270,16 @@ local scroll_fs =
 --style_type[label;border=;bgcolor=]
 --label[0.75,2;Reset]
 
+local window = {
+       sizex = 12,
+       sizey = 13,
+       positionx = 0.5,
+       positiony = 0.5,
+       anchorx = 0.5,
+       anchory = 0.5,
+       paddingx = 0.05,
+       paddingy = 0.05
+}
 
 local pages = {
        -- Real Coordinates
@@ -341,9 +351,28 @@ local pages = {
                "size[12,13]real_coordinates[true]" ..
                "container[0.5,1.5]" .. tabheaders_fs .. "container_end[]",
 
-               -- Inv
+       -- Inv
                "size[12,13]real_coordinates[true]" .. inv_style_fs,
 
+       -- Window
+               function()
+                       return "formspec_version[3]" ..
+                               string.format("size[%s,%s]position[%s,%s]anchor[%s,%s]padding[%s,%s]",
+                                       window.sizex, window.sizey, window.positionx, window.positiony,
+                                       window.anchorx, window.anchory, window.paddingx, window.paddingy) ..
+                               string.format("field[0.5,0.5;2.5,0.5;sizex;X Size;%s]field[3.5,0.5;2.5,0.5;sizey;Y Size;%s]" ..
+                                       "field[0.5,1.5;2.5,0.5;positionx;X Position;%s]field[3.5,1.5;2.5,0.5;positiony;Y Position;%s]" ..
+                                       "field[0.5,2.5;2.5,0.5;anchorx;X Anchor;%s]field[3.5,2.5;2.5,0.5;anchory;Y Anchor;%s]" ..
+                                       "field[0.5,3.5;2.5,0.5;paddingx;X Padding;%s]field[3.5,3.5;2.5,0.5;paddingy;Y Padding;%s]" ..
+                                       "button[2,4.5;2.5,0.5;submit_window;Submit]",
+                                       window.sizex, window.sizey, window.positionx, window.positiony,
+                                       window.anchorx, window.anchory, window.paddingx, window.paddingy) ..
+                               "field_close_on_enter[sizex;false]field_close_on_enter[sizey;false]" ..
+                               "field_close_on_enter[positionx;false]field_close_on_enter[positiony;false]" ..
+                               "field_close_on_enter[anchorx;false]field_close_on_enter[anchory;false]" ..
+                               "field_close_on_enter[paddingx;false]field_close_on_enter[paddingy;false]"
+               end,
+
        -- Animation
                [[
                        formspec_version[3]
@@ -401,12 +430,43 @@ mouse control = true]
                        checkbox[0.5,5.5.5;snd_chk;Sound;]
                        tabheader[0.5,7;8,0.65;snd_tab;Soundtab1,Soundtab2,Soundtab3;1;false;false]
                ]],
+
+       -- Background
+               [[
+                       formspec_version[3]
+                       size[12,13]
+                       box[0,0;12,13;#f0f1]
+                       background[0,0;0,0;testformspec_bg.png;true]
+                       box[3.9,2.9;6.2,4.2;#d00f]
+                       scroll_container[4,3;6,4;scrbar;vertical]
+                               background9[1,0.5;0,0;testformspec_bg_9slice.png;true;4,6]
+                               label[0,0.2;Backgrounds are not be applied to scroll containers,]
+                               label[0,0.5;but to the whole form.]
+                       scroll_container_end[]
+                       scrollbar[3.5,3;0.3,4;vertical;scrbar;0]
+                       container[2,11]
+                               box[-0.1,0.5;3.2,1;#fff5]
+                               background[0,0;2,3;testformspec_bg.png;false]
+                               background9[1,0;2,3;testformspec_bg_9slice.png;false;4,6]
+                       container_end[]
+               ]],
+
+       -- Unsized
+               [[
+                       formspec_version[3]
+                       background9[0,0;0,0;testformspec_bg_9slice.png;true;4,6]
+                       background[1,1;0,0;testformspec_bg.png;true]
+               ]],
 }
 
-local function show_test_formspec(pname, page_id)
-       page_id = page_id or 2
+local page_id = 2
+local function show_test_formspec(pname)
+       local page = pages[page_id]
+       if type(page) == "function" then
+               page = page()
+       end
 
-       local fs = pages[page_id] .. "tabheader[0,0;8,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Anim,Model,ScrollC,Sound;" .. page_id .. ";false;false]"
+       local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]"
 
        minetest.show_formspec(pname, "testformspec:formspec", fs)
 end
@@ -416,9 +476,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
                return false
        end
 
-
        if fields.maintabs then
-               show_test_formspec(player:get_player_name(), tonumber(fields.maintabs))
+               page_id = tonumber(fields.maintabs)
+               show_test_formspec(player:get_player_name())
                return true
        end
 
@@ -434,6 +494,26 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
                minetest.chat_send_player(player:get_player_name(), "Hypertext action received: " .. tostring(fields.hypertext))
                return true
        end
+
+       for name, value in pairs(fields) do
+               if window[name] then
+                       print(name, window[name])
+                       local num_val = tonumber(value) or 0
+
+                       if name == "sizex" and num_val < 4 then
+                               num_val = 6.5
+                       elseif name == "sizey" and num_val < 5 then
+                               num_val = 5.5
+                       end
+
+                       window[name] = num_val
+                       print(name, window[name])
+               end
+       end
+
+       if fields.submit_window then
+               show_test_formspec(player:get_player_name())
+       end
 end)
 
 minetest.register_chatcommand("test_formspec", {
index 3d2ea17f5e65c50f7d18fadded605c574ce8a49b..be33814af81b4f6d95e3d1d78d330e5af1c2f9fc 100644 (file)
@@ -40,9 +40,11 @@ for d=0, 8 do
                liquid_range = d,
        })
 
+       if d <= 7 then
+
        local mod = "^[colorize:#000000:127"
        minetest.register_node("testnodes:vliquid_"..d, {
-               description = "Test Liquid Source, Viscosity "..d,
+               description = "Test Liquid Source, Viscosity/Resistance "..d,
                drawtype = "liquid",
                tiles = {"testnodes_liquidsource_r"..d..".png"..mod},
                special_tiles = {
@@ -61,7 +63,7 @@ for d=0, 8 do
        })
 
        minetest.register_node("testnodes:vliquid_flowing_"..d, {
-               description = "Flowing Test Liquid, Viscosity "..d,
+               description = "Flowing Test Liquid, Viscosity/Resistance "..d,
                drawtype = "flowingliquid",
                tiles = {"testnodes_liquidflowing_r"..d..".png"..mod},
                special_tiles = {
@@ -80,4 +82,53 @@ for d=0, 8 do
                liquid_viscosity = d,
        })
 
+       mod = "^[colorize:#000000:192"
+       local v = 4
+       minetest.register_node("testnodes:vrliquid_"..d, {
+               description = "Test Liquid Source, Viscosity "..v..", Resistance "..d,
+               drawtype = "liquid",
+               tiles = {"testnodes_liquidsource_r"..d..".png"..mod},
+               special_tiles = {
+                       {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false},
+                       {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true},
+               },
+               use_texture_alpha = "blend",
+               paramtype = "light",
+               walkable = false,
+               pointable = false,
+               diggable = false,
+               buildable_to = true,
+               is_ground_content = false,
+               liquidtype = "source",
+               liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d,
+               liquid_alternative_source = "testnodes:vrliquid_"..d,
+               liquid_viscosity = v,
+               move_resistance = d,
+       })
+
+       minetest.register_node("testnodes:vrliquid_flowing_"..d, {
+               description = "Flowing Test Liquid, Viscosity "..v..", Resistance "..d,
+               drawtype = "flowingliquid",
+               tiles = {"testnodes_liquidflowing_r"..d..".png"..mod},
+               special_tiles = {
+                       {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
+                       {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false},
+               },
+               use_texture_alpha = "blend",
+               paramtype = "light",
+               paramtype2 = "flowingliquid",
+               walkable = false,
+               pointable = false,
+               diggable = false,
+               buildable_to = true,
+               is_ground_content = false,
+               liquidtype = "flowing",
+               liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d,
+               liquid_alternative_source = "testnodes:vrliquid_"..d,
+               liquid_viscosity = v,
+               move_resistance = d,
+       })
+
+       end
+
 end
index a52cd1d6fa8e2778f8733cd0514b56e8b1ee28dd..89facf71c3dd71822919a9f31845e28f8a365a28 100644 (file)
@@ -152,6 +152,66 @@ minetest.register_node("testnodes:liquidflowing_nojump", {
        post_effect_color = {a = 70, r = 255, g = 0, b = 200},
 })
 
+-- A liquid which doesn't have liquid movement physics (source variant)
+minetest.register_node("testnodes:liquid_noswim", {
+       description = S("No-swim Liquid Source Node"),
+       liquidtype = "source",
+       liquid_range = 1,
+       liquid_viscosity = 0,
+       liquid_alternative_flowing = "testnodes:liquidflowing_noswim",
+       liquid_alternative_source = "testnodes:liquid_noswim",
+       liquid_renewable = false,
+       liquid_move_physics = false,
+       groups = {dig_immediate=3},
+       walkable = false,
+
+       drawtype = "liquid",
+       tiles = {"testnodes_liquidsource.png^[colorize:#FF00FF:127"},
+       special_tiles = {
+               {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = false},
+               {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = true},
+       },
+       use_texture_alpha = "blend",
+       paramtype = "light",
+       pointable = false,
+       liquids_pointable = true,
+       buildable_to = true,
+       is_ground_content = false,
+       post_effect_color = {a = 70, r = 255, g = 200, b = 200},
+})
+
+-- A liquid which doen't have liquid movement physics (flowing variant)
+minetest.register_node("testnodes:liquidflowing_noswim", {
+       description = S("No-swim Flowing Liquid Node"),
+       liquidtype = "flowing",
+       liquid_range = 1,
+       liquid_viscosity = 0,
+       liquid_alternative_flowing = "testnodes:liquidflowing_noswim",
+       liquid_alternative_source = "testnodes:liquid_noswim",
+       liquid_renewable = false,
+       liquid_move_physics = false,
+       groups = {dig_immediate=3},
+       walkable = false,
+
+
+       drawtype = "flowingliquid",
+       tiles = {"testnodes_liquidflowing.png^[colorize:#FF00FF:127"},
+       special_tiles = {
+               {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false},
+               {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false},
+       },
+       use_texture_alpha = "blend",
+       paramtype = "light",
+       paramtype2 = "flowingliquid",
+       pointable = false,
+       liquids_pointable = true,
+       buildable_to = true,
+       is_ground_content = false,
+       post_effect_color = {a = 70, r = 255, g = 200, b = 200},
+})
+
+
+
 -- Nodes that modify fall damage (various damage modifiers)
 for i=-100, 100, 25 do
        if i ~= 0 then
@@ -192,9 +252,9 @@ for i=-100, 100, 25 do
 end
 
 -- Bouncy nodes (various bounce levels)
-for i=20, 180, 20 do
+for i=-140, 180, 20 do
        local val = math.floor(((i-20)/200)*255)
-       minetest.register_node("testnodes:bouncy"..i, {
+       minetest.register_node(("testnodes:bouncy"..i):gsub("-","NEG"), {
                description = S("Bouncy Node (@1%)", i),
                groups = {bouncy=i, dig_immediate=3},
 
@@ -216,6 +276,54 @@ for i=1, 5 do
        })
 end
 
+-- Move resistance nodes (various resistance levels)
+for r=0, 7 do
+       if r > 0 then
+               minetest.register_node("testnodes:move_resistance"..r, {
+                       description = S("Move-resistant Node (@1)", r),
+                       walkable = false,
+                       move_resistance = r,
+
+                       drawtype = "glasslike",
+                       paramtype = "light",
+                       sunlight_propagates = true,
+                       tiles = { "testnodes_move_resistance.png" },
+                       is_ground_content = false,
+                       groups = { dig_immediate = 3 },
+                       color = { b = 0, g = 255, r = math.floor((r/7)*255), a = 255 },
+               })
+       end
+
+       minetest.register_node("testnodes:move_resistance_liquidlike"..r, {
+               description = S("Move-resistant Node, liquidlike (@1)", r),
+               walkable = false,
+               move_resistance = r,
+               liquid_move_physics = true,
+
+               drawtype = "glasslike",
+               paramtype = "light",
+               sunlight_propagates = true,
+               tiles = { "testnodes_move_resistance.png" },
+               is_ground_content = false,
+               groups = { dig_immediate = 3 },
+               color = { b = 255, g = 0, r = math.floor((r/7)*255), a = 255 },
+       })
+end
+
+minetest.register_node("testnodes:climbable_move_resistance_4", {
+       description = S("Climbable Move-resistant Node (4)"),
+       walkable = false,
+       climbable = true,
+       move_resistance = 4,
+
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = {"testnodes_climbable_resistance_side.png"},
+       is_ground_content = false,
+       groups = { dig_immediate = 3 },
+})
+
 -- By placing something on the node, the node itself will be replaced
 minetest.register_node("testnodes:buildable_to", {
        description = S("Replacable Node"),
index 4652007d941a330122a4d48fd5913c27d54f4848..2faacdd78be85cbf3a76f528e2a4c9214f5f48a2 100644 (file)
@@ -102,12 +102,22 @@ local function gen_checkers(w, h, tile)
 end
 
 local fractal = mandelbrot(512, 512, 128)
+local frac_emb = mandelbrot(64, 64, 64)
 local checker = gen_checkers(512, 512, 32)
 
 local floor = math.floor
 local abs = math.abs
+local data_emb = {}
 local data_mb = {}
 local data_ck = {}
+for i=1, #frac_emb do
+       data_emb[i] = {
+               r = floor(abs(frac_emb[i] * 2 - 1) * 255),
+               g = floor(abs(1 - frac_emb[i]) * 255),
+               b = floor(frac_emb[i] * 255),
+               a = frac_emb[i] < 0.95 and 255 or 0,
+       }
+end
 for i=1, #fractal do
        data_mb[i] = {
                r = floor(fractal[i] * 255),
@@ -140,3 +150,141 @@ minetest.register_node("testnodes:generated_png_ck", {
 
        groups = { dig_immediate = 2 },
 })
+
+local png_emb = "[png:" .. minetest.encode_base64(minetest.encode_png(64,64,data_emb))
+
+minetest.register_node("testnodes:generated_png_emb", {
+       description = S("Generated In-Band Mandelbrot PNG Test Node"),
+       tiles = { png_emb },
+
+       groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:generated_png_src_emb", {
+       description = S("Generated In-Band Source Blit Mandelbrot PNG Test Node"),
+       tiles = { png_emb .. "^testnodes_damage_neg.png" },
+
+       groups = { dig_immediate = 2 },
+})
+minetest.register_node("testnodes:generated_png_dst_emb", {
+       description = S("Generated In-Band Dest Blit Mandelbrot PNG Test Node"),
+       tiles = { "testnodes_generated_ck.png^" .. png_emb },
+
+       groups = { dig_immediate = 2 },
+})
+
+--[[
+
+The following nodes can be used to demonstrate the TGA format support.
+
+Minetest supports TGA types 1, 2, 3 & 10. While adding the support for
+TGA type 9 (RLE-compressed, color-mapped) is easy, it is not advisable
+to do so, as it is not backwards compatible with any Minetest pre-5.5;
+content creators should therefore either use TGA type 1 or 10, or PNG.
+
+TODO: Types 1, 2 & 10 should have two test nodes each (i.e. bottom-top
+and top-bottom) for 16bpp (A1R5G5B5), 24bpp (B8G8R8), 32bpp (B8G8R8A8)
+colors.
+
+Note: Minetest requires the optional TGA footer for a texture to load.
+If a TGA image does not load in Minetest, append eight (8) null bytes,
+then the string “TRUEVISION-XFILE.”, then another null byte.
+
+]]--
+
+minetest.register_node("testnodes:tga_type1_24bpp_bt", {
+       description = S("TGA Type 1 (color-mapped RGB) 24bpp bottom-top Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type1_24bpp_bt.tga" },
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type1_24bpp_tb", {
+       description = S("TGA Type 1 (color-mapped RGB) 24bpp top-bottom Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type1_24bpp_tb.tga" },
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_16bpp_bt", {
+       description = S("TGA Type 2 (uncompressed RGB) 16bpp bottom-top Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type2_16bpp_bt.tga" },
+       use_texture_alpha = "clip",
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_16bpp_tb", {
+       description = S("TGA Type 2 (uncompressed RGB) 16bpp top-bottom Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type2_16bpp_tb.tga" },
+       use_texture_alpha = "clip",
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_32bpp_bt", {
+       description = S("TGA Type 2 (uncompressed RGB) 32bpp bottom-top Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type2_32bpp_bt.tga" },
+       use_texture_alpha = "blend",
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type2_32bpp_tb", {
+       description = S("TGA Type 2 (uncompressed RGB) 32bpp top-bottom Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type2_32bpp_tb.tga" },
+       use_texture_alpha = "blend",
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type3_16bpp_bt", {
+       description = S("TGA Type 3 (uncompressed grayscale) 16bpp bottom-top Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type3_16bpp_bt.tga" },
+       use_texture_alpha = "blend",
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type3_16bpp_tb", {
+       description = S("TGA Type 3 (uncompressed grayscale) 16bpp top-bottom Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type3_16bpp_tb.tga" },
+       use_texture_alpha = "blend",
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type10_32bpp_bt", {
+       description = S("TGA Type 10 (RLE-compressed RGB) 32bpp bottom-top Test Node"),
+       tiles = { "testnodes_tga_type10_32bpp_bt.tga" },
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       use_texture_alpha = "blend",
+       groups = { dig_immediate = 2 },
+})
+
+minetest.register_node("testnodes:tga_type10_32bpp_tb", {
+       description = S("TGA Type 10 (RLE-compressed RGB) 32bpp top-bottom Test Node"),
+       drawtype = "glasslike",
+       paramtype = "light",
+       sunlight_propagates = true,
+       tiles = { "testnodes_tga_type10_32bpp_tb.tga" },
+       use_texture_alpha = "blend",
+       groups = { dig_immediate = 2 },
+})
diff --git a/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png b/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png
new file mode 100644 (file)
index 0000000..be01583
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_climbable_resistance_side.png differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png b/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png
new file mode 100644 (file)
index 0000000..cac3944
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_move_resistance.png differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga
new file mode 100644 (file)
index 0000000..2dc587b
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga
new file mode 100644 (file)
index 0000000..b44a81c
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga
new file mode 100644 (file)
index 0000000..d2c2ca6
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga
new file mode 100644 (file)
index 0000000..dfcb988
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga
new file mode 100644 (file)
index 0000000..0206216
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga
new file mode 100644 (file)
index 0000000..2563f08
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga
new file mode 100644 (file)
index 0000000..3350500
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga
new file mode 100644 (file)
index 0000000..216de06
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga
new file mode 100644 (file)
index 0000000..695bb4b
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga differ
diff --git a/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga
new file mode 100644 (file)
index 0000000..c08a093
Binary files /dev/null and b/games/devtest/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga differ
diff --git a/games/devtest/mods/unittests/async_env.lua b/games/devtest/mods/unittests/async_env.lua
new file mode 100644 (file)
index 0000000..3a21bd9
--- /dev/null
@@ -0,0 +1,168 @@
+-- helper
+
+core.register_async_dofile(core.get_modpath(core.get_current_modname()) ..
+       DIR_DELIM .. "inside_async_env.lua")
+
+local function deepequal(a, b)
+       if type(a) == "function" then
+               return type(b) == "function"
+       elseif type(a) ~= "table" then
+               return a == b
+       elseif type(b) ~= "table" then
+               return false
+       end
+       for k, v in pairs(a) do
+               if not deepequal(v, b[k]) then
+                       return false
+               end
+       end
+       for k, v in pairs(b) do
+               if not deepequal(a[k], v) then
+                       return false
+               end
+       end
+       return true
+end
+
+-- Object Passing / Serialization
+
+local test_object = {
+       name = "stairs:stair_glass",
+       type = "node",
+       groups = {oddly_breakable_by_hand = 3, cracky = 3, stair = 1},
+       description = "Glass Stair",
+       sounds = {
+               dig = {name = "default_glass_footstep", gain = 0.5},
+               footstep = {name = "default_glass_footstep", gain = 0.3},
+               dug = {name = "default_break_glass", gain = 1}
+       },
+       node_box = {
+               fixed = {
+                       {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+                       {-0.5, 0, 0, 0.5, 0.5, 0.5}
+               },
+               type = "fixed"
+       },
+       tiles = {
+               {name = "stairs_glass_split.png", backface_culling = true},
+               {name = "default_glass.png", backface_culling = true},
+               {name = "stairs_glass_stairside.png^[transformFX", backface_culling = true}
+       },
+       on_place = function(itemstack, placer)
+               return core.is_player(placer)
+       end,
+       sunlight_propagates = true,
+       is_ground_content = false,
+       light_source = 0,
+}
+
+local function test_object_passing()
+       local tmp = core.serialize_roundtrip(test_object)
+       assert(deepequal(test_object, tmp))
+
+       local circular_key = {"foo", "bar"}
+       circular_key[circular_key] = true
+       tmp = core.serialize_roundtrip(circular_key)
+       assert(tmp[1] == "foo")
+       assert(tmp[2] == "bar")
+       assert(tmp[tmp] == true)
+
+       local circular_value = {"foo"}
+       circular_value[2] = circular_value
+       tmp = core.serialize_roundtrip(circular_value)
+       assert(tmp[1] == "foo")
+       assert(tmp[2] == tmp)
+
+       -- Two-segment cycle
+       local cycle_seg_1, cycle_seg_2 = {}, {}
+       cycle_seg_1[1] = cycle_seg_2
+       cycle_seg_2[1] = cycle_seg_1
+       tmp = core.serialize_roundtrip(cycle_seg_1)
+       assert(tmp[1][1] == tmp)
+
+       -- Duplicated value without a cycle
+       local acyclic_dup_holder = {}
+       tmp = ItemStack("")
+       acyclic_dup_holder[tmp] = tmp
+       tmp = core.serialize_roundtrip(acyclic_dup_holder)
+       for k, v in pairs(tmp) do
+               assert(rawequal(k, v))
+       end
+end
+unittests.register("test_object_passing", test_object_passing)
+
+local function test_userdata_passing(_, pos)
+       -- basic userdata passing
+       local obj = table.copy(test_object.tiles[1])
+       obj.test = ItemStack("default:cobble 99")
+       local tmp = core.serialize_roundtrip(obj)
+       assert(type(tmp.test) == "userdata")
+       assert(obj.test:to_string() == tmp.test:to_string())
+
+       -- object can't be passed, should error
+       obj = core.raycast(pos, pos)
+       assert(not pcall(core.serialize_roundtrip, obj))
+
+       -- VManip
+       local vm = core.get_voxel_manip(pos, pos)
+       local expect = vm:get_node_at(pos)
+       local vm2 = core.serialize_roundtrip(vm)
+       assert(deepequal(vm2:get_node_at(pos), expect))
+end
+unittests.register("test_userdata_passing", test_userdata_passing, {map=true})
+
+-- Asynchronous jobs
+
+local function test_handle_async(cb)
+       -- Basic test including mod name tracking and unittests.async_test()
+       -- which is defined inside_async_env.lua
+       local func = function(x)
+               return core.get_last_run_mod(), _VERSION, unittests[x]()
+       end
+       local expect = {core.get_last_run_mod(), _VERSION, true}
+
+       core.handle_async(func, function(...)
+               if not deepequal(expect, {...}) then
+                       cb("Values did not equal")
+               end
+               if core.get_last_run_mod() ~= expect[1] then
+                       cb("Mod name not tracked correctly")
+               end
+
+               -- Test passing of nil arguments and return values
+               core.handle_async(function(a, b)
+                       return a, b
+               end, function(a, b)
+                       if b ~= 123 then
+                               cb("Argument went missing")
+                       end
+                       cb()
+               end, nil, 123)
+       end, "async_test")
+end
+unittests.register("test_handle_async", test_handle_async, {async=true})
+
+local function test_userdata_passing2(cb, _, pos)
+       -- VManip: check transfer into other env
+       local vm = core.get_voxel_manip(pos, pos)
+       local expect = vm:get_node_at(pos)
+
+       core.handle_async(function(vm_, pos_)
+               return vm_:get_node_at(pos_)
+       end, function(ret)
+               if not deepequal(expect, ret) then
+                       cb("Node data mismatch (one-way)")
+               end
+
+               -- VManip: test a roundtrip
+               core.handle_async(function(vm_)
+                       return vm_
+               end, function(vm2)
+                       if not deepequal(expect, vm2:get_node_at(pos)) then
+                               cb("Node data mismatch (roundtrip)")
+                       end
+                       cb()
+               end, vm)
+       end, vm, pos)
+end
+unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true})
index eff13ce090e009cc215a5777f50b8fd1c5fac6b7..8c16d3efb3f884d4c80a5681450e42254360536c 100644 (file)
@@ -1,6 +1,7 @@
+dofile(core.get_modpath(core.get_current_modname()) .. "/crafting_prepare.lua")
+
 -- Test minetest.clear_craft function
 local function test_clear_craft()
-       minetest.log("info", "[unittests] Testing minetest.clear_craft")
        -- Clearing by output
        minetest.register_craft({
                output = "foo",
@@ -22,11 +23,10 @@ local function test_clear_craft()
        minetest.clear_craft({recipe={{"foo", "bar"}}})
        assert(minetest.get_all_craft_recipes("foo") == nil)
 end
+unittests.register("test_clear_craft", test_clear_craft)
 
 -- Test minetest.get_craft_result function
 local function test_get_craft_result()
-       minetest.log("info", "[unittests] Testing minetest.get_craft_result")
-
        -- normal
        local input = {
                method = "normal",
@@ -107,14 +107,6 @@ local function test_get_craft_result()
        assert(output.item)
        minetest.log("info", "[unittests] unrepairable tool crafting output.item:to_table(): "..dump(output.item:to_table()))
        -- unrepairable tool must not yield any output
-       assert(output.item:get_name() == "")
-
+       assert(output.item:is_empty())
 end
-
-function unittests.test_crafting()
-       test_clear_craft()
-       test_get_craft_result()
-       minetest.log("action", "[unittests] Crafting tests passed!")
-       return true
-end
-
+unittests.register("test_get_craft_result", test_get_craft_result)
index a09734827db79e230bc31b40cd4b9dd3dfbc3ade..5cf5775e014d4a4c7a4699056e21b88f9671aefd 100644 (file)
@@ -31,25 +31,31 @@ minetest.register_craftitem("unittests:steel_ingot", {
        groups = { dummy = 1 },
 })
 
+-- Use aliases in recipes for more complete testing
+
+minetest.register_alias("unittests:steel_ingot_alias", "unittests:steel_ingot")
+minetest.register_alias("unittests:coal_lump_alias", "unittests:coal_lump")
+minetest.register_alias("unittests:iron_lump_alias", "unittests:iron_lump")
+
 -- Recipes for tests: Normal crafting, cooking and fuel
 
 minetest.register_craft({
        output = 'unittests:torch 4',
        recipe = {
-               {'unittests:coal_lump'},
+               {'unittests:coal_lump_alias'},
                {'unittests:stick'},
        }
 })
 
 minetest.register_craft({
        type = "cooking",
-       output = "unittests:steel_ingot",
-       recipe = "unittests:iron_lump",
+       output = "unittests:steel_ingot_alias",
+       recipe = "unittests:iron_lump_alias",
 })
 
 minetest.register_craft({
        type = "fuel",
-       recipe = "unittests:coal_lump",
+       recipe = "unittests:coal_lump_alias",
        burntime = 40,
 })
 
index 12c67f78beb072958a35297d72d82862548e3de8..0608f2dd21ed18a91bd146d07d0cef7c7e047492 100644 (file)
 unittests = {}
 
+unittests.list = {}
+
+-- name: Name of the test
+-- func:
+--   for sync: function(player, pos), should error on failure
+--   for async: function(callback, player, pos)
+--     MUST call callback() or callback("error msg") in case of error once test is finished
+--     this means you cannot use assert() in the test implementation
+-- opts: {
+--   player = false, -- Does test require a player?
+--   map = false, -- Does test require map access?
+--   async = false, -- Does the test run asynchronously? (read notes above!)
+-- }
+function unittests.register(name, func, opts)
+       local def = table.copy(opts or {})
+       def.name = name
+       def.func = func
+       table.insert(unittests.list, def)
+end
+
+function unittests.on_finished(all_passed)
+       -- free to override
+end
+
+-- Calls invoke with a callback as argument
+-- Suspends coroutine until that callback is called
+-- Return values are passed through
+local function await(invoke)
+       local co = coroutine.running()
+       assert(co)
+       local called_early = true
+       invoke(function(...)
+               if called_early == true then
+                       called_early = {...}
+               else
+                       coroutine.resume(co, ...)
+               end
+       end)
+       if called_early ~= true then
+               -- callback was already called before yielding
+               return unpack(called_early)
+       end
+       called_early = nil
+       return coroutine.yield()
+end
+
+function unittests.run_one(idx, counters, out_callback, player, pos)
+       local def = unittests.list[idx]
+       if not def.player then
+               player = nil
+       elseif player == nil then
+               out_callback(false)
+               return false
+       end
+       if not def.map then
+               pos = nil
+       elseif pos == nil then
+               out_callback(false)
+               return false
+       end
+
+       local tbegin = core.get_us_time()
+       local function done(status, err)
+               local tend = core.get_us_time()
+               local ms_taken = (tend - tbegin) / 1000
+
+               if not status then
+                       core.log("error", err)
+               end
+               print(string.format("[%s] %s - %dms",
+                       status and "PASS" or "FAIL", def.name, ms_taken))
+               counters.time = counters.time + ms_taken
+               counters.total = counters.total + 1
+               if status then
+                       counters.passed = counters.passed + 1
+               end
+       end
+
+       if def.async then
+               core.log("info", "[unittest] running " .. def.name .. " (async)")
+               def.func(function(err)
+                       done(err == nil, err)
+                       out_callback(true)
+               end, player, pos)
+       else
+               core.log("info", "[unittest] running " .. def.name)
+               local status, err = pcall(def.func, player, pos)
+               done(status, err)
+               out_callback(true)
+       end
+       
+       return true
+end
+
+local function wait_for_player(callback)
+       if #core.get_connected_players() > 0 then
+               return callback(core.get_connected_players()[1])
+       end
+       local first = true
+       core.register_on_joinplayer(function(player)
+               if first then
+                       callback(player)
+                       first = false
+               end
+       end)
+end
+
+local function wait_for_map(player, callback)
+       local check = function()
+               if core.get_node_or_nil(player:get_pos()) ~= nil then
+                       callback()
+               else
+                       minetest.after(0, check)
+               end
+       end
+       check()
+end
+
+function unittests.run_all()
+       -- This runs in a coroutine so it uses await().
+       local counters = { time = 0, total = 0, passed = 0 }
+
+       -- Run standalone tests first
+       for idx = 1, #unittests.list do
+               local def = unittests.list[idx]
+               def.done = await(function(cb)
+                       unittests.run_one(idx, counters, cb, nil, nil)
+               end)
+       end
+
+       -- Wait for a player to join, run tests that require a player
+       local player = await(wait_for_player)
+       for idx = 1, #unittests.list do
+               local def = unittests.list[idx]
+               if not def.done then
+                       def.done = await(function(cb)
+                               unittests.run_one(idx, counters, cb, player, nil)
+                       end)
+               end
+       end
+
+       -- Wait for the world to generate/load, run tests that require map access
+       await(function(cb)
+               wait_for_map(player, cb)
+       end)
+       local pos = vector.round(player:get_pos())
+       for idx = 1, #unittests.list do
+               local def = unittests.list[idx]
+               if not def.done then
+                       def.done = await(function(cb)
+                               unittests.run_one(idx, counters, cb, player, pos)
+                       end)
+               end
+       end
+
+       -- Print stats
+       assert(#unittests.list == counters.total)
+       print(string.rep("+", 80))
+       print(string.format("Unit Test Results: %s",
+       counters.total == counters.passed and "PASSED" or "FAILED"))
+       print(string.format("    %d / %d failed tests.",
+       counters.total - counters.passed, counters.total))
+       print(string.format("    Testing took %dms total.", counters.time))
+       print(string.rep("+", 80))
+       unittests.on_finished(counters.total == counters.passed)
+       return counters.total == counters.passed
+end
+
+--------------
+
 local modpath = minetest.get_modpath("unittests")
-dofile(modpath .. "/random.lua")
+dofile(modpath .. "/misc.lua")
 dofile(modpath .. "/player.lua")
-dofile(modpath .. "/crafting_prepare.lua")
 dofile(modpath .. "/crafting.lua")
 dofile(modpath .. "/itemdescription.lua")
+dofile(modpath .. "/async_env.lua")
+
+--------------
 
-if minetest.settings:get_bool("devtest_unittests_autostart", false) then
-       unittests.test_random()
-       unittests.test_crafting()
-       unittests.test_short_desc()
-       minetest.register_on_joinplayer(function(player)
-               unittests.test_player(player)
+if core.settings:get_bool("devtest_unittests_autostart", false) then
+       core.after(0, function()
+               coroutine.wrap(unittests.run_all)()
        end)
+else
+       minetest.register_chatcommand("unittests", {
+               privs = {basic_privs=true},
+               description = "Runs devtest unittests (may modify player or map state)",
+               func = function(name, param)
+                       unittests.on_finished = function(ok)
+                               core.chat_send_player(name,
+                                       (ok and "All tests passed." or "There were test failures.") ..
+                                       " Check the console for detailed output.")
+                       end
+                       coroutine.wrap(unittests.run_all)()
+                       return true, ""
+               end,
+       })
 end
-
diff --git a/games/devtest/mods/unittests/inside_async_env.lua b/games/devtest/mods/unittests/inside_async_env.lua
new file mode 100644 (file)
index 0000000..9774771
--- /dev/null
@@ -0,0 +1,15 @@
+unittests = {}
+
+core.log("info", "Hello World")
+
+function unittests.async_test()
+       assert(core == minetest)
+       -- stuff that should not be here
+       assert(not core.get_player_by_name)
+       assert(not core.set_node)
+       assert(not core.object_refs)
+       -- stuff that should be here
+       assert(ItemStack)
+       assert(core.registered_items[""])
+       return true
+end
index d6ee6551affbce9a35a235e9d9577b00c5ed8699..b4c218c987cda689f8557252a61611b816a68000 100644 (file)
@@ -1,17 +1,7 @@
-local full_description = "Colorful Pickaxe\nThe best pick."
-minetest.register_tool("unittests:colorful_pick", {
+local full_description = "Description Test Item\nFor testing item decription"
+minetest.register_tool("unittests:description_test", {
        description = full_description,
-       inventory_image = "basetools_mesepick.png",
-       tool_capabilities = {
-               full_punch_interval = 1.0,
-               max_drop_level=3,
-               groupcaps={
-                       cracky={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
-                       crumbly={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3},
-                       snappy={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=20, maxlevel=3}
-               },
-               damage_groups = {fleshy=4},
-       },
+       inventory_image = "unittests_description_test.png",
 })
 
 minetest.register_chatcommand("item_description", {
@@ -25,23 +15,23 @@ minetest.register_chatcommand("item_description", {
        end
 })
 
-function unittests.test_short_desc()
+local function test_short_desc()
        local function get_short_description(item)
                return ItemStack(item):get_short_description()
        end
 
-       local stack = ItemStack("unittests:colorful_pick")
-       assert(stack:get_short_description() == "Colorful Pickaxe")
-       assert(get_short_description("unittests:colorful_pick") == "Colorful Pickaxe")
-       assert(minetest.registered_items["unittests:colorful_pick"].short_description == nil)
+       local stack = ItemStack("unittests:description_test")
+       assert(stack:get_short_description() == "Description Test Item")
+       assert(get_short_description("unittests:description_test") == "Description Test Item")
+       assert(minetest.registered_items["unittests:description_test"].short_description == nil)
        assert(stack:get_description() == full_description)
-       assert(stack:get_description() == minetest.registered_items["unittests:colorful_pick"].description)
+       assert(stack:get_description() == minetest.registered_items["unittests:description_test"].description)
 
        stack:get_meta():set_string("description", "Hello World")
        assert(stack:get_short_description() == "Hello World")
        assert(stack:get_description() == "Hello World")
        assert(get_short_description(stack) == "Hello World")
-       assert(get_short_description("unittests:colorful_pick") == "Colorful Pickaxe")
+       assert(get_short_description("unittests:description_test") == "Description Test Item")
 
        stack:get_meta():set_string("short_description", "Foo Bar")
        assert(stack:get_short_description() == "Foo Bar")
@@ -49,3 +39,4 @@ function unittests.test_short_desc()
 
        return true
 end
+unittests.register("test_short_desc", test_short_desc)
diff --git a/games/devtest/mods/unittests/misc.lua b/games/devtest/mods/unittests/misc.lua
new file mode 100644 (file)
index 0000000..ba98086
--- /dev/null
@@ -0,0 +1,50 @@
+local function test_random()
+       -- Try out PseudoRandom
+       local pseudo = PseudoRandom(13)
+       assert(pseudo:next() == 22290)
+       assert(pseudo:next() == 13854)
+end
+unittests.register("test_random", test_random)
+
+local function test_dynamic_media(cb, player)
+       if core.get_player_information(player:get_player_name()).protocol_version < 40 then
+               core.log("warning", "test_dynamic_media: Client too old, skipping test.")
+               return cb()
+       end
+
+       -- Check that the client acknowledges media transfers
+       local path = core.get_worldpath() .. "/test_media.obj"
+       local f = io.open(path, "w")
+       f:write("# contents don't matter\n")
+       f:close()
+
+       local call_ok = false
+       local ok = core.dynamic_add_media({
+               filepath = path,
+               to_player = player:get_player_name(),
+       }, function(name)
+               if not call_ok then
+                       cb("impossible condition")
+               end
+               cb()
+       end)
+       if not ok then
+               return cb("dynamic_add_media() returned error")
+       end
+       call_ok = true
+
+       -- if the callback isn't called this test will just hang :shrug:
+end
+unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true})
+
+local function test_v3f_metatable(player)
+       assert(vector.check(player:get_pos()))
+end
+unittests.register("test_v3f_metatable", test_v3f_metatable, {player=true})
+
+local function test_v3s16_metatable(player, pos)
+       local node = minetest.get_node(pos)
+       local found_pos = minetest.find_node_near(pos, 0, node.name, true)
+       assert(vector.check(found_pos))
+end
+unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true})
index 4a681310dc0acd3402e9e7de8bb96a366b867cc0..fa0557960580020ebcbb0871d9923afe94c2d5be 100644 (file)
@@ -2,6 +2,21 @@
 -- HP Change Reasons
 --
 local expect = nil
+minetest.register_on_player_hpchange(function(player, hp, reason)
+       if expect == nil then
+               return
+       end
+
+       for key, value in pairs(reason) do
+               assert(expect[key] == value)
+       end
+       for key, value in pairs(expect) do
+               assert(reason[key] == value)
+       end
+
+       expect = nil
+end)
+
 local function run_hpchangereason_tests(player)
        local old_hp = player:get_hp()
 
@@ -20,7 +35,11 @@ local function run_hpchangereason_tests(player)
 
        player:set_hp(old_hp)
 end
+unittests.register("test_hpchangereason", run_hpchangereason_tests, {player=true})
 
+--
+-- Player meta
+--
 local function run_player_meta_tests(player)
        local meta = player:get_meta()
        meta:set_string("foo", "bar")
@@ -48,29 +67,4 @@ local function run_player_meta_tests(player)
        assert(meta:get_string("foo") == "")
        assert(meta:equals(meta2))
 end
-
-function unittests.test_player(player)
-       minetest.register_on_player_hpchange(function(player, hp, reason)
-               if not expect then
-                       return
-               end
-
-               for key, value in pairs(reason) do
-                       assert(expect[key] == value)
-               end
-
-               for key, value in pairs(expect) do
-                       assert(reason[key] == value)
-               end
-
-               expect = nil
-       end)
-
-       run_hpchangereason_tests(player)
-       run_player_meta_tests(player)
-       local msg = "Player tests passed for player '"..player:get_player_name().."'!"
-       minetest.chat_send_all(msg)
-       minetest.log("action", "[unittests] "..msg)
-       return true
-end
-
+unittests.register("test_player_meta", run_player_meta_tests, {player=true})
diff --git a/games/devtest/mods/unittests/random.lua b/games/devtest/mods/unittests/random.lua
deleted file mode 100644 (file)
index f94f0a8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-function unittests.test_random()
-       -- Try out PseudoRandom
-       minetest.log("action", "[unittests] Testing PseudoRandom ...")
-       local pseudo = PseudoRandom(13)
-       assert(pseudo:next() == 22290)
-       assert(pseudo:next() == 13854)
-       minetest.log("action", "[unittests] PseudoRandom test passed!")
-       return true
-end
-
diff --git a/games/devtest/mods/unittests/textures/unittests_description_test.png b/games/devtest/mods/unittests/textures/unittests_description_test.png
new file mode 100644 (file)
index 0000000..a6be433
Binary files /dev/null and b/games/devtest/mods/unittests/textures/unittests_description_test.png differ
index ca5dca2d950114ec10f862f246cb125c3fcb6e74..c37364042f8cc7b2607cfb12e4c55f3379ac7f27 100644 (file)
@@ -114,6 +114,59 @@ minetest.register_chatcommand("detach", {
        end,
 })
 
+minetest.register_chatcommand("use_tool", {
+       params = "(dig <group> <leveldiff>) | (hit <damage_group> <time_from_last_punch>) [<uses>]",
+       description = "Apply tool wear a number of times, as if it were used for digging",
+       func = function(name, param)
+               local player = minetest.get_player_by_name(name)
+               if not player then
+                       return false, "No player."
+               end
+               local mode, group, level, uses = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+) (%d+)")
+               if not mode then
+                       mode, group, level = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+)")
+                       uses = 1
+               end
+               if not mode or not group or not level then
+                       return false
+               end
+               if mode ~= "dig" and mode ~= "hit" then
+                       return false
+               end
+               local tool = player:get_wielded_item()
+               local caps = tool:get_tool_capabilities()
+               if not caps or tool:get_count() == 0 then
+                       return false, "No tool in hand."
+               end
+               local actual_uses = 0
+               for u=1, uses do
+                       local wear = tool:get_wear()
+                       local dp
+                       if mode == "dig" then
+                               dp = minetest.get_dig_params({[group]=3, level=level}, caps, wear)
+                       else
+                               dp = minetest.get_hit_params({[group]=100}, caps, level, wear)
+                       end
+                       tool:add_wear(dp.wear)
+                       actual_uses = actual_uses + 1
+                       if tool:get_count() == 0 then
+                               break
+                       end
+               end
+               player:set_wielded_item(tool)
+               if tool:get_count() == 0 then
+                       return true, string.format("Tool used %d time(s). "..
+                                       "The tool broke after %d use(s).", uses, actual_uses)
+               else
+                       local wear = tool:get_wear()
+                       return true, string.format("Tool used %d time(s). "..
+                                       "Final wear=%d", uses, wear)
+               end
+       end,
+})
+
+
+
 -- Use this to test waypoint capabilities
 minetest.register_chatcommand("test_waypoints", {
        params = "[change_immediate]",
@@ -193,3 +246,64 @@ function minetest.handle_node_drops(pos, drops, digger)
                end
        end
 end
+
+minetest.register_chatcommand("set_displayed_itemcount", {
+       params = "(-s \"<string>\" [-c <color>]) | -a <alignment_num>",
+       description = "Set the displayed itemcount of the wielded item",
+       func = function(name, param)
+               local player = minetest.get_player_by_name(name)
+               local item = player:get_wielded_item()
+               local meta = item:get_meta()
+               local flag1 = param:sub(1, 2)
+               if flag1 == "-s" then
+                       if param:sub(3, 4) ~= " \"" then
+                               return false, "Error: Space and string with \"s expected after -s."
+                       end
+                       local se = param:find("\"", 5, true)
+                       if not se then
+                               return false, "Error: String with two \"s expected after -s."
+                       end
+                       local s = param:sub(5, se - 1)
+                       if param:sub(se + 1, se + 4) == " -c " then
+                               s = minetest.colorize(param:sub(se + 5), s)
+                       end
+                       meta:set_string("count_meta", s)
+               elseif flag1 == "-a" then
+                       local num = tonumber(param:sub(4))
+                       if not num then
+                               return false, "Error: Invalid number: "..param:sub(4)
+                       end
+                       meta:set_int("count_alignment", num)
+               else
+                       return false
+               end
+               player:set_wielded_item(item)
+               return true, "Displayed itemcount set."
+       end,
+})
+
+minetest.register_chatcommand("dump_item", {
+       params = "",
+       description = "Prints a dump of the wielded item in table form",
+       func = function(name, param)
+               local player = minetest.get_player_by_name(name)
+               local item = player:get_wielded_item()
+               local str = dump(item:to_table())
+               print(str)
+               return true, str
+       end,
+})
+
+-- shadow control
+minetest.register_on_joinplayer(function (player)
+       player:set_lighting({shadows={intensity = 0.33}})
+end)
+
+core.register_chatcommand("set_shadow", {
+    params = "<shadow_intensity>",
+    description = "Set shadow parameters of current player.",
+    func = function(player_name, param)
+        local shadow_intensity = tonumber(param)
+        minetest.get_player_by_name(player_name):set_lighting({shadows = { intensity = shadow_intensity} })
+    end
+})
diff --git a/lib/bitop/CMakeLists.txt b/lib/bitop/CMakeLists.txt
new file mode 100644 (file)
index 0000000..02e8a42
--- /dev/null
@@ -0,0 +1,4 @@
+add_library(bitop STATIC bit.c)
+target_link_libraries(bitop)
+
+include_directories(${LUA_INCLUDE_DIR})
diff --git a/lib/bitop/bit.c b/lib/bitop/bit.c
new file mode 100644 (file)
index 0000000..f23c31a
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+** Lua BitOp -- a bit operations library for Lua 5.1/5.2.
+** http://bitop.luajit.org/
+**
+** Copyright (C) 2008-2012 Mike Pall. All rights reserved.
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+*/
+
+#include "bit.h"
+
+#define LUA_BITOP_VERSION      "1.0.2"
+
+#define LUA_LIB
+#include "lauxlib.h"
+
+#ifdef _MSC_VER
+/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+typedef int32_t SBits;
+typedef uint32_t UBits;
+
+typedef union {
+  lua_Number n;
+#ifdef LUA_NUMBER_DOUBLE
+  uint64_t b;
+#else
+  UBits b;
+#endif
+} BitNum;
+
+/* Convert argument to bit type. */
+static UBits barg(lua_State *L, int idx)
+{
+  BitNum bn;
+  UBits b;
+#if LUA_VERSION_NUM < 502
+  bn.n = lua_tonumber(L, idx);
+#else
+  bn.n = luaL_checknumber(L, idx);
+#endif
+#if defined(LUA_NUMBER_DOUBLE)
+  bn.n += 6755399441055744.0;  /* 2^52+2^51 */
+#ifdef SWAPPED_DOUBLE
+  b = (UBits)(bn.b >> 32);
+#else
+  b = (UBits)bn.b;
+#endif
+#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \
+      defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \
+      defined(LUA_NUMBER_LLONG)
+  if (sizeof(UBits) == sizeof(lua_Number))
+    b = bn.b;
+  else
+    b = (UBits)(SBits)bn.n;
+#elif defined(LUA_NUMBER_FLOAT)
+#error "A 'float' lua_Number type is incompatible with this library"
+#else
+#error "Unknown number type, check LUA_NUMBER_* in luaconf.h"
+#endif
+#if LUA_VERSION_NUM < 502
+  if (b == 0 && !lua_isnumber(L, idx)) {
+    luaL_typerror(L, idx, "number");
+  }
+#endif
+  return b;
+}
+
+/* Return bit type. */
+#define BRET(b)  lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1;
+
+static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) }
+static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) }
+
+#define BIT_OP(func, opr) \
+  static int func(lua_State *L) { int i; UBits b = barg(L, 1); \
+    for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) }
+BIT_OP(bit_band, &=)
+BIT_OP(bit_bor, |=)
+BIT_OP(bit_bxor, ^=)
+
+#define bshl(b, n)  (b << n)
+#define bshr(b, n)  (b >> n)
+#define bsar(b, n)  ((SBits)b >> n)
+#define brol(b, n)  ((b << n) | (b >> (32-n)))
+#define bror(b, n)  ((b << (32-n)) | (b >> n))
+#define BIT_SH(func, fn) \
+  static int func(lua_State *L) { \
+    UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) }
+BIT_SH(bit_lshift, bshl)
+BIT_SH(bit_rshift, bshr)
+BIT_SH(bit_arshift, bsar)
+BIT_SH(bit_rol, brol)
+BIT_SH(bit_ror, bror)
+
+static int bit_bswap(lua_State *L)
+{
+  UBits b = barg(L, 1);
+  b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24);
+  BRET(b)
+}
+
+static int bit_tohex(lua_State *L)
+{
+  UBits b = barg(L, 1);
+  SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
+  const char *hexdigits = "0123456789abcdef";
+  char buf[8];
+  int i;
+  if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
+  if (n > 8) n = 8;
+  for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
+  lua_pushlstring(L, buf, (size_t)n);
+  return 1;
+}
+
+static const struct luaL_Reg bit_funcs[] = {
+  { "tobit",   bit_tobit },
+  { "bnot",    bit_bnot },
+  { "band",    bit_band },
+  { "bor",     bit_bor },
+  { "bxor",    bit_bxor },
+  { "lshift",  bit_lshift },
+  { "rshift",  bit_rshift },
+  { "arshift", bit_arshift },
+  { "rol",     bit_rol },
+  { "ror",     bit_ror },
+  { "bswap",   bit_bswap },
+  { "tohex",   bit_tohex },
+  { NULL, NULL }
+};
+
+/* Signed right-shifts are implementation-defined per C89/C99.
+** But the de facto standard are arithmetic right-shifts on two's
+** complement CPUs. This behaviour is required here, so test for it.
+*/
+#define BAD_SAR                (bsar(-8, 2) != (SBits)-2)
+
+LUALIB_API int luaopen_bit(lua_State *L)
+{
+  UBits b;
+  lua_pushnumber(L, (lua_Number)1437217655L);
+  b = barg(L, -1);
+  if (b != (UBits)1437217655L || BAD_SAR) {  /* Perform a simple self-test. */
+    const char *msg = "compiled with incompatible luaconf.h";
+#ifdef LUA_NUMBER_DOUBLE
+#ifdef _WIN32
+    if (b == (UBits)1610612736L)
+      msg = "use D3DCREATE_FPU_PRESERVE with DirectX";
+#endif
+    if (b == (UBits)1127743488L)
+      msg = "not compiled with SWAPPED_DOUBLE";
+#endif
+    if (BAD_SAR)
+      msg = "arithmetic right-shift broken";
+    luaL_error(L, "bit library self-test failed (%s)", msg);
+  }
+#if LUA_VERSION_NUM < 502
+  luaL_register(L, "bit", bit_funcs);
+#else
+  luaL_newlib(L, bit_funcs);
+#endif
+  return 1;
+}
diff --git a/lib/bitop/bit.h b/lib/bitop/bit.h
new file mode 100644 (file)
index 0000000..3e5845e
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+** Lua BitOp -- a bit operations library for Lua 5.1/5.2.
+** http://bitop.luajit.org/
+**
+** Copyright (C) 2008-2012 Mike Pall. All rights reserved.
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+*/
+
+#pragma once
+
+#include "lua.h"
+
+#define LUA_BITLIBNAME "bit"
+LUALIB_API int luaopen_bit(lua_State *L);
diff --git a/lib/catch2/CMakeLists.txt b/lib/catch2/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3c471d4
--- /dev/null
@@ -0,0 +1,16 @@
+# catch2 is distributed as a standalone header.
+#
+# Downloaded from:
+#
+#      https://github.com/catchorg/Catch2/releases/download/v2.13.9/catch.hpp
+#
+# The following changes were made to always print in microseconds, fixed format:
+#
+# -    explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
+# +    explicit Duration(double inNanoseconds, Unit units = Unit::Microseconds)
+#
+# -        return os << duration.value() << ' ' << duration.unitsAsString();
+# +        return os << std::fixed << duration.value() << ' ' << duration.unitsAsString();
+
+add_library(catch2 INTERFACE)
+target_include_directories(catch2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/lib/catch2/catch.hpp b/lib/catch2/catch.hpp
new file mode 100644 (file)
index 0000000..88f1106
--- /dev/null
@@ -0,0 +1,17970 @@
+/*
+ *  Catch v2.13.9
+ *  Generated: 2022-04-12 22:37:23.260201
+ *  ----------------------------------------------------------
+ *  This file has been merged from multiple headers. Please don't edit it directly
+ *  Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved.
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+// start catch.hpp
+
+
+#define CATCH_VERSION_MAJOR 2
+#define CATCH_VERSION_MINOR 13
+#define CATCH_VERSION_PATCH 9
+
+#ifdef __clang__
+#    pragma clang system_header
+#elif defined __GNUC__
+#    pragma GCC system_header
+#endif
+
+// start catch_suppress_warnings.h
+
+#ifdef __clang__
+#   ifdef __ICC // icpc defines the __clang__ macro
+#       pragma warning(push)
+#       pragma warning(disable: 161 1682)
+#   else // __ICC
+#       pragma clang diagnostic push
+#       pragma clang diagnostic ignored "-Wpadded"
+#       pragma clang diagnostic ignored "-Wswitch-enum"
+#       pragma clang diagnostic ignored "-Wcovered-switch-default"
+#    endif
+#elif defined __GNUC__
+     // Because REQUIREs trigger GCC's -Wparentheses, and because still
+     // supported version of g++ have only buggy support for _Pragmas,
+     // Wparentheses have to be suppressed globally.
+#    pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
+
+#    pragma GCC diagnostic push
+#    pragma GCC diagnostic ignored "-Wunused-variable"
+#    pragma GCC diagnostic ignored "-Wpadded"
+#endif
+// end catch_suppress_warnings.h
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+#  define CATCH_IMPL
+#  define CATCH_CONFIG_ALL_PARTS
+#endif
+
+// In the impl file, we want to have access to all parts of the headers
+// Can also be used to sanely support PCHs
+#if defined(CATCH_CONFIG_ALL_PARTS)
+#  define CATCH_CONFIG_EXTERNAL_INTERFACES
+#  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#    undef CATCH_CONFIG_DISABLE_MATCHERS
+#  endif
+#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  endif
+#endif
+
+#if !defined(CATCH_CONFIG_IMPL_ONLY)
+// start catch_platform.h
+
+// See e.g.:
+// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
+#ifdef __APPLE__
+#  include <TargetConditionals.h>
+#  if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
+      (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
+#    define CATCH_PLATFORM_MAC
+#  elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
+#    define CATCH_PLATFORM_IPHONE
+#  endif
+
+#elif defined(linux) || defined(__linux) || defined(__linux__)
+#  define CATCH_PLATFORM_LINUX
+
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
+#  define CATCH_PLATFORM_WINDOWS
+#endif
+
+// end catch_platform.h
+
+#ifdef CATCH_IMPL
+#  ifndef CLARA_CONFIG_MAIN
+#    define CLARA_CONFIG_MAIN_NOT_DEFINED
+#    define CLARA_CONFIG_MAIN
+#  endif
+#endif
+
+// start catch_user_interfaces.h
+
+namespace Catch {
+    unsigned int rngSeed();
+}
+
+// end catch_user_interfaces.h
+// start catch_tag_alias_autoregistrar.h
+
+// start catch_common.h
+
+// start catch_compiler_capabilities.h
+
+// Detect a number of compiler features - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
+// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
+// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
+// ****************
+// Note to maintainers: if new toggles are added please document them
+// in configuration.md, too
+// ****************
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+#ifdef __cplusplus
+
+#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
+#    define CATCH_CPP14_OR_GREATER
+#  endif
+
+#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+#    define CATCH_CPP17_OR_GREATER
+#  endif
+
+#endif
+
+// Only GCC compiler should be used in this block, so other compilers trying to
+// mask themselves as GCC should be ignored.
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
+#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
+#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "GCC diagnostic pop" )
+
+#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
+
+#endif
+
+#if defined(__clang__)
+
+#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
+#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
+
+// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
+// which results in calls to destructors being emitted for each temporary,
+// without a matching initialization. In practice, this can result in something
+// like `std::string::~string` being called on an uninitialized value.
+//
+// For example, this code will likely segfault under IBM XL:
+// ```
+// REQUIRE(std::string("12") + "34" == "1234")
+// ```
+//
+// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
+#  if !defined(__ibmxl__) && !defined(__CUDACC__)
+#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
+#  endif
+
+#    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
+         _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
+
+#    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+
+#    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
+
+#    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
+
+#    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+         _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Assume that non-Windows platforms support posix signals by default
+#if !defined(CATCH_PLATFORM_WINDOWS)
+    #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// We know some environments not to support full POSIX signals
+#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
+    #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+#endif
+
+#ifdef __OS400__
+#       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+#       define CATCH_CONFIG_COLOUR_NONE
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Android somehow still does not support std::to_string
+#if defined(__ANDROID__)
+#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+#    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Not all Windows environments support SEH properly
+#if defined(__MINGW32__)
+#    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// PS4
+#if defined(__ORBIS__)
+#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Cygwin
+#ifdef __CYGWIN__
+
+// Required for some versions of Cygwin to declare gettimeofday
+// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
+#   define _BSD_SOURCE
+// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
+// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
+# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
+           && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
+
+#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+
+# endif
+#endif // __CYGWIN__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#if defined(_MSC_VER)
+
+// Universal Windows platform does not support SEH
+// Or console colours (or console at all...)
+#  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
+#    define CATCH_CONFIG_COLOUR_NONE
+#  else
+#    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
+#  endif
+
+#  if !defined(__clang__) // Handle Clang masquerading for msvc
+
+// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
+// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
+// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
+#    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
+#      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#    endif // MSVC_TRADITIONAL
+
+// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`
+#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
+#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
+#  endif // __clang__
+
+#endif // _MSC_VER
+
+#if defined(_REENTRANT) || defined(_MSC_VER)
+// Enable async processing, as -pthread is specified or no additional linking is required
+# define CATCH_INTERNAL_CONFIG_USE_ASYNC
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+// Check if we are compiled with -fno-exceptions or equivalent
+#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
+#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// DJGPP
+#ifdef __DJGPP__
+#  define CATCH_INTERNAL_CONFIG_NO_WCHAR
+#endif // __DJGPP__
+
+////////////////////////////////////////////////////////////////////////////////
+// Embarcadero C++Build
+#if defined(__BORLANDC__)
+    #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use of __COUNTER__ is suppressed during code analysis in
+// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
+// handled by it.
+// Otherwise all supported compilers support COUNTER macro,
+// but user still might want to turn it off
+#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
+    #define CATCH_INTERNAL_CONFIG_COUNTER
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+// RTX is a special version of Windows that is real time.
+// This means that it is detected as Windows, but does not provide
+// the same set of capabilities as real Windows does.
+#if defined(UNDER_RTSS) || defined(RTX64_BUILD)
+    #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
+    #define CATCH_INTERNAL_CONFIG_NO_ASYNC
+    #define CATCH_CONFIG_COLOUR_NONE
+#endif
+
+#if !defined(_GLIBCXX_USE_C99_MATH_TR1)
+#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
+#endif
+
+// Various stdlib support checks that require __has_include
+#if defined(__has_include)
+  // Check if string_view is available and usable
+  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+  #endif
+
+  // Check if optional is available and usable
+  #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+  #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
+  #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+
+  // Check if byte is available and usable
+  #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+  #    include <cstddef>
+  #    if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
+  #      define CATCH_INTERNAL_CONFIG_CPP17_BYTE
+  #    endif
+  #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+
+  // Check if variant is available and usable
+  #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+  #    if defined(__clang__) && (__clang_major__ < 8)
+         // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
+         // fix should be in clang 8, workaround in libstdc++ 8.2
+  #      include <ciso646>
+  #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+  #        define CATCH_CONFIG_NO_CPP17_VARIANT
+  #      else
+  #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+  #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+  #    else
+  #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+  #    endif // defined(__clang__) && (__clang_major__ < 8)
+  #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // defined(__has_include)
+
+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
+#   define CATCH_CONFIG_COUNTER
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
+#   define CATCH_CONFIG_WINDOWS_SEH
+#endif
+// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
+#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
+#   define CATCH_CONFIG_POSIX_SIGNALS
+#endif
+// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
+#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
+#   define CATCH_CONFIG_WCHAR
+#endif
+
+#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
+#    define CATCH_CONFIG_CPP11_TO_STRING
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
+#  define CATCH_CONFIG_CPP17_OPTIONAL
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
+#  define CATCH_CONFIG_CPP17_STRING_VIEW
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
+#  define CATCH_CONFIG_CPP17_VARIANT
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
+#  define CATCH_CONFIG_CPP17_BYTE
+#endif
+
+#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
+#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
+#  define CATCH_CONFIG_NEW_CAPTURE
+#endif
+
+#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#  define CATCH_CONFIG_DISABLE_EXCEPTIONS
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
+#  define CATCH_CONFIG_POLYFILL_ISNAN
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
+#  define CATCH_CONFIG_USE_ASYNC
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+#  define CATCH_CONFIG_ANDROID_LOGWRITE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+#  define CATCH_CONFIG_GLOBAL_NEXTAFTER
+#endif
+
+// Even if we do not think the compiler has that warning, we still have
+// to provide a macro that can be used by the code.
+#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
+#   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
+#endif
+#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
+#   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+#endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
+#endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+#endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
+#endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
+#endif
+
+// The goal of this macro is to avoid evaluation of the arguments, but
+// still have the compiler warn on problems inside...
+#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
+#   define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
+#endif
+
+#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
+#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#elif defined(__clang__) && (__clang_major__ < 5)
+#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#endif
+
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#define CATCH_TRY if ((true))
+#define CATCH_CATCH_ALL if ((false))
+#define CATCH_CATCH_ANON(type) if ((false))
+#else
+#define CATCH_TRY try
+#define CATCH_CATCH_ALL catch (...)
+#define CATCH_CATCH_ANON(type) catch (type)
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
+#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#endif
+
+// end catch_compiler_capabilities.h
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#ifdef CATCH_CONFIG_COUNTER
+#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
+#else
+#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+#endif
+
+#include <iosfwd>
+#include <string>
+#include <cstdint>
+
+// We need a dummy global operator<< so we can bring it into Catch namespace later
+struct Catch_global_namespace_dummy {};
+std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
+
+namespace Catch {
+
+    struct CaseSensitive { enum Choice {
+        Yes,
+        No
+    }; };
+
+    class NonCopyable {
+        NonCopyable( NonCopyable const& )              = delete;
+        NonCopyable( NonCopyable && )                  = delete;
+        NonCopyable& operator = ( NonCopyable const& ) = delete;
+        NonCopyable& operator = ( NonCopyable && )     = delete;
+
+    protected:
+        NonCopyable();
+        virtual ~NonCopyable();
+    };
+
+    struct SourceLineInfo {
+
+        SourceLineInfo() = delete;
+        SourceLineInfo( char const* _file, std::size_t _line ) noexcept
+        :   file( _file ),
+            line( _line )
+        {}
+
+        SourceLineInfo( SourceLineInfo const& other )            = default;
+        SourceLineInfo& operator = ( SourceLineInfo const& )     = default;
+        SourceLineInfo( SourceLineInfo&& )              noexcept = default;
+        SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
+
+        bool empty() const noexcept { return file[0] == '\0'; }
+        bool operator == ( SourceLineInfo const& other ) const noexcept;
+        bool operator < ( SourceLineInfo const& other ) const noexcept;
+
+        char const* file;
+        std::size_t line;
+    };
+
+    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+    // Bring in operator<< from global namespace into Catch namespace
+    // This is necessary because the overload of operator<< above makes
+    // lookup stop at namespace Catch
+    using ::operator<<;
+
+    // Use this in variadic streaming macros to allow
+    //    >> +StreamEndStop
+    // as well as
+    //    >> stuff +StreamEndStop
+    struct StreamEndStop {
+        std::string operator+() const;
+    };
+    template<typename T>
+    T const& operator + ( T const& value, StreamEndStop ) {
+        return value;
+    }
+}
+
+#define CATCH_INTERNAL_LINEINFO \
+    ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+
+// end catch_common.h
+namespace Catch {
+
+    struct RegistrarForTagAliases {
+        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+    };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+    namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+// end catch_tag_alias_autoregistrar.h
+// start catch_test_registry.h
+
+// start catch_interfaces_testcase.h
+
+#include <vector>
+
+namespace Catch {
+
+    class TestSpec;
+
+    struct ITestInvoker {
+        virtual void invoke () const = 0;
+        virtual ~ITestInvoker();
+    };
+
+    class TestCase;
+    struct IConfig;
+
+    struct ITestCaseRegistry {
+        virtual ~ITestCaseRegistry();
+        virtual std::vector<TestCase> const& getAllTests() const = 0;
+        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
+    };
+
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config );
+    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+}
+
+// end catch_interfaces_testcase.h
+// start catch_stringref.h
+
+#include <cstddef>
+#include <string>
+#include <iosfwd>
+#include <cassert>
+
+namespace Catch {
+
+    /// A non-owning string class (similar to the forthcoming std::string_view)
+    /// Note that, because a StringRef may be a substring of another string,
+    /// it may not be null terminated.
+    class StringRef {
+    public:
+        using size_type = std::size_t;
+        using const_iterator = const char*;
+
+    private:
+        static constexpr char const* const s_empty = "";
+
+        char const* m_start = s_empty;
+        size_type m_size = 0;
+
+    public: // construction
+        constexpr StringRef() noexcept = default;
+
+        StringRef( char const* rawChars ) noexcept;
+
+        constexpr StringRef( char const* rawChars, size_type size ) noexcept
+        :   m_start( rawChars ),
+            m_size( size )
+        {}
+
+        StringRef( std::string const& stdString ) noexcept
+        :   m_start( stdString.c_str() ),
+            m_size( stdString.size() )
+        {}
+
+        explicit operator std::string() const {
+            return std::string(m_start, m_size);
+        }
+
+    public: // operators
+        auto operator == ( StringRef const& other ) const noexcept -> bool;
+        auto operator != (StringRef const& other) const noexcept -> bool {
+            return !(*this == other);
+        }
+
+        auto operator[] ( size_type index ) const noexcept -> char {
+            assert(index < m_size);
+            return m_start[index];
+        }
+
+    public: // named queries
+        constexpr auto empty() const noexcept -> bool {
+            return m_size == 0;
+        }
+        constexpr auto size() const noexcept -> size_type {
+            return m_size;
+        }
+
+        // Returns the current start pointer. If the StringRef is not
+        // null-terminated, throws std::domain_exception
+        auto c_str() const -> char const*;
+
+    public: // substrings and searches
+        // Returns a substring of [start, start + length).
+        // If start + length > size(), then the substring is [start, size()).
+        // If start > size(), then the substring is empty.
+        auto substr( size_type start, size_type length ) const noexcept -> StringRef;
+
+        // Returns the current start pointer. May not be null-terminated.
+        auto data() const noexcept -> char const*;
+
+        constexpr auto isNullTerminated() const noexcept -> bool {
+            return m_start[m_size] == '\0';
+        }
+
+    public: // iterators
+        constexpr const_iterator begin() const { return m_start; }
+        constexpr const_iterator end() const { return m_start + m_size; }
+    };
+
+    auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
+    auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
+
+    constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
+        return StringRef( rawChars, size );
+    }
+} // namespace Catch
+
+constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
+    return Catch::StringRef( rawChars, size );
+}
+
+// end catch_stringref.h
+// start catch_preprocessor.hpp
+
+
+#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
+#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
+#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
+#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
+#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
+#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
+
+#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
+// MSVC needs more evaluations
+#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
+#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
+#else
+#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)
+#endif
+
+#define CATCH_REC_END(...)
+#define CATCH_REC_OUT
+
+#define CATCH_EMPTY()
+#define CATCH_DEFER(id) id CATCH_EMPTY()
+
+#define CATCH_REC_GET_END2() 0, CATCH_REC_END
+#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
+#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
+#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
+#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
+#define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
+
+#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
+#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
+#define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
+
+#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
+#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
+#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
+
+// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
+// and passes userdata as the first parameter to each invocation,
+// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
+#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
+
+#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
+
+#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
+#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
+#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
+#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
+#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
+#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
+#else
+// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
+#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
+#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
+#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
+#endif
+
+#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
+#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
+
+#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
+#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
+#else
+#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
+#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
+#endif
+
+#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
+    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
+
+#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
+#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
+#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
+#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
+#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
+#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
+#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
+#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
+#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
+#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
+#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
+
+#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
+
+#define INTERNAL_CATCH_TYPE_GEN\
+    template<typename...> struct TypeList {};\
+    template<typename...Ts>\
+    constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
+    template<template<typename...> class...> struct TemplateTypeList{};\
+    template<template<typename...> class...Cs>\
+    constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
+    template<typename...>\
+    struct append;\
+    template<typename...>\
+    struct rewrap;\
+    template<template<typename...> class, typename...>\
+    struct create;\
+    template<template<typename...> class, typename>\
+    struct convert;\
+    \
+    template<typename T> \
+    struct append<T> { using type = T; };\
+    template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
+    struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
+    template< template<typename...> class L1, typename...E1, typename...Rest>\
+    struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
+    \
+    template< template<typename...> class Container, template<typename...> class List, typename...elems>\
+    struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
+    template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
+    struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
+    \
+    template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
+    struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
+    template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
+    struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
+
+#define INTERNAL_CATCH_NTTP_1(signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
+    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
+    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
+    constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
+    \
+    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
+    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
+    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
+    template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
+    struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    static void TestName()
+
+#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
+    template<typename Type>\
+    void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
+    template<typename Type>\
+    void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
+    void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
+    {\
+        Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
+    }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
+    template<typename TestType> \
+    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
+        void test();\
+    }
+
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
+    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
+        void test();\
+    }
+
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
+    template<typename TestType> \
+    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
+    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
+    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define INTERNAL_CATCH_NTTP_0
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
+#else
+#define INTERNAL_CATCH_NTTP_0(signature)
+#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
+#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
+#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
+#endif
+
+// end catch_preprocessor.hpp
+// start catch_meta.hpp
+
+
+#include <type_traits>
+
+namespace Catch {
+    template<typename T>
+    struct always_false : std::false_type {};
+
+    template <typename> struct true_given : std::true_type {};
+    struct is_callable_tester {
+        template <typename Fun, typename... Args>
+        true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
+        template <typename...>
+        std::false_type static test(...);
+    };
+
+    template <typename T>
+    struct is_callable;
+
+    template <typename Fun, typename... Args>
+    struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
+
+#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
+    // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
+    // replaced with std::invoke_result here.
+    template <typename Func, typename... U>
+    using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
+#else
+    // Keep ::type here because we still support C++11
+    template <typename Func, typename... U>
+    using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
+#endif
+
+} // namespace Catch
+
+namespace mpl_{
+    struct na;
+}
+
+// end catch_meta.hpp
+namespace Catch {
+
+template<typename C>
+class TestInvokerAsMethod : public ITestInvoker {
+    void (C::*m_testAsMethod)();
+public:
+    TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
+
+    void invoke() const override {
+        C obj;
+        (obj.*m_testAsMethod)();
+    }
+};
+
+auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
+
+template<typename C>
+auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
+    return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
+}
+
+struct NameAndTags {
+    NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
+    StringRef name;
+    StringRef tags;
+};
+
+struct AutoReg : NonCopyable {
+    AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
+    ~AutoReg();
+};
+
+} // end namespace Catch
+
+#if defined(CATCH_CONFIG_DISABLE)
+    #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
+        static void TestName()
+    #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
+        namespace{                        \
+            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
+                void test();              \
+            };                            \
+        }                                 \
+        void TestName::test()
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \
+        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \
+        namespace{                                                                                  \
+            namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \
+            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+        }                                                                                           \
+        }                                                                                           \
+        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+    #endif
+
+    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+    #else
+        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
+            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+    #endif
+#endif
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+        static void TestName(); \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+        static void TestName()
+    #define INTERNAL_CATCH_TESTCASE( ... ) \
+        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        namespace{ \
+            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
+                void test(); \
+            }; \
+            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+        } \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+        void TestName::test()
+    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
+        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+            INTERNAL_CATCH_TYPE_GEN\
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            template<typename...Types> \
+            struct TestName{\
+                TestName(){\
+                    int index = 0;                                    \
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
+                    using expander = int[];\
+                    (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
+                }\
+            };\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+            TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
+            return 0;\
+        }();\
+        }\
+        }\
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
+
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \
+        template<typename TestType> static void TestFuncName();       \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \
+            INTERNAL_CATCH_TYPE_GEN                                                  \
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \
+            template<typename... Types>                               \
+            struct TestName {                                         \
+                void reg_tests() {                                          \
+                    int index = 0;                                    \
+                    using expander = int[];                           \
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
+                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
+                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
+                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\
+                }                                                     \
+            };                                                        \
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
+                using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
+                TestInit t;                                           \
+                t.reg_tests();                                        \
+                return 0;                                             \
+            }();                                                      \
+        }                                                             \
+        }                                                             \
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
+        template<typename TestType>                                   \
+        static void TestFuncName()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__)
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__)
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
+
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        template<typename TestType> static void TestFunc();       \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
+        INTERNAL_CATCH_TYPE_GEN\
+        template<typename... Types>                               \
+        struct TestName {                                         \
+            void reg_tests() {                                          \
+                int index = 0;                                    \
+                using expander = int[];                           \
+                (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
+            }                                                     \
+        };\
+        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
+                using TestInit = typename convert<TestName, TmplList>::type; \
+                TestInit t;                                           \
+                t.reg_tests();                                        \
+                return 0;                                             \
+            }();                                                      \
+        }}\
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \
+        template<typename TestType>                                   \
+        static void TestFunc()
+
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
+        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList )
+
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+            INTERNAL_CATCH_TYPE_GEN\
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
+            INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            template<typename...Types> \
+            struct TestNameClass{\
+                TestNameClass(){\
+                    int index = 0;                                    \
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
+                    using expander = int[];\
+                    (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
+                }\
+            };\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+                TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
+                return 0;\
+        }();\
+        }\
+        }\
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
+#endif
+
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        template<typename TestType> \
+            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
+                void test();\
+            };\
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
+            INTERNAL_CATCH_TYPE_GEN                  \
+            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+            template<typename...Types>\
+            struct TestNameClass{\
+                void reg_tests(){\
+                    int index = 0;\
+                    using expander = int[];\
+                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
+                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
+                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
+                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \
+                }\
+            };\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+                using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
+                TestInit t;\
+                t.reg_tests();\
+                return 0;\
+            }(); \
+        }\
+        }\
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+        template<typename TestType> \
+        void TestName<TestType>::test()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )
+#endif
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )
+#else
+    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
+        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
+#endif
+
+    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
+        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+        template<typename TestType> \
+        struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
+            void test();\
+        };\
+        namespace {\
+        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+            INTERNAL_CATCH_TYPE_GEN\
+            template<typename...Types>\
+            struct TestNameClass{\
+                void reg_tests(){\
+                    int index = 0;\
+                    using expander = int[];\
+                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
+                }\
+            };\
+            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+                using TestInit = typename convert<TestNameClass, TmplList>::type;\
+                TestInit t;\
+                t.reg_tests();\
+                return 0;\
+            }(); \
+        }}\
+        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+        template<typename TestType> \
+        void TestName<TestType>::test()
+
+#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
+        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList )
+
+// end catch_test_registry.h
+// start catch_capture.hpp
+
+// start catch_assertionhandler.h
+
+// start catch_assertioninfo.h
+
+// start catch_result_type.h
+
+namespace Catch {
+
+    // ResultWas::OfType enum
+    struct ResultWas { enum OfType {
+        Unknown = -1,
+        Ok = 0,
+        Info = 1,
+        Warning = 2,
+
+        FailureBit = 0x10,
+
+        ExpressionFailed = FailureBit | 1,
+        ExplicitFailure = FailureBit | 2,
+
+        Exception = 0x100 | FailureBit,
+
+        ThrewException = Exception | 1,
+        DidntThrowException = Exception | 2,
+
+        FatalErrorCondition = 0x200 | FailureBit
+
+    }; };
+
+    bool isOk( ResultWas::OfType resultType );
+    bool isJustInfo( int flags );
+
+    // ResultDisposition::Flags enum
+    struct ResultDisposition { enum Flags {
+        Normal = 0x01,
+
+        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
+        FalseTest = 0x04,           // Prefix expression with !
+        SuppressFail = 0x08         // Failures are reported but do not fail the test
+    }; };
+
+    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
+
+    bool shouldContinueOnFailure( int flags );
+    inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+    bool shouldSuppressFailure( int flags );
+
+} // end namespace Catch
+
+// end catch_result_type.h
+namespace Catch {
+
+    struct AssertionInfo
+    {
+        StringRef macroName;
+        SourceLineInfo lineInfo;
+        StringRef capturedExpression;
+        ResultDisposition::Flags resultDisposition;
+
+        // We want to delete this constructor but a compiler bug in 4.8 means
+        // the struct is then treated as non-aggregate
+        //AssertionInfo() = delete;
+    };
+
+} // end namespace Catch
+
+// end catch_assertioninfo.h
+// start catch_decomposer.h
+
+// start catch_tostring.h
+
+#include <vector>
+#include <cstddef>
+#include <type_traits>
+#include <string>
+// start catch_stream.h
+
+#include <iosfwd>
+#include <cstddef>
+#include <ostream>
+
+namespace Catch {
+
+    std::ostream& cout();
+    std::ostream& cerr();
+    std::ostream& clog();
+
+    class StringRef;
+
+    struct IStream {
+        virtual ~IStream();
+        virtual std::ostream& stream() const = 0;
+    };
+
+    auto makeStream( StringRef const &filename ) -> IStream const*;
+
+    class ReusableStringStream : NonCopyable {
+        std::size_t m_index;
+        std::ostream* m_oss;
+    public:
+        ReusableStringStream();
+        ~ReusableStringStream();
+
+        auto str() const -> std::string;
+
+        template<typename T>
+        auto operator << ( T const& value ) -> ReusableStringStream& {
+            *m_oss << value;
+            return *this;
+        }
+        auto get() -> std::ostream& { return *m_oss; }
+    };
+}
+
+// end catch_stream.h
+// start catch_interfaces_enum_values_registry.h
+
+#include <vector>
+
+namespace Catch {
+
+    namespace Detail {
+        struct EnumInfo {
+            StringRef m_name;
+            std::vector<std::pair<int, StringRef>> m_values;
+
+            ~EnumInfo();
+
+            StringRef lookup( int value ) const;
+        };
+    } // namespace Detail
+
+    struct IMutableEnumValuesRegistry {
+        virtual ~IMutableEnumValuesRegistry();
+
+        virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
+
+        template<typename E>
+        Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
+            static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
+            std::vector<int> intValues;
+            intValues.reserve( values.size() );
+            for( auto enumValue : values )
+                intValues.push_back( static_cast<int>( enumValue ) );
+            return registerEnum( enumName, allEnums, intValues );
+        }
+    };
+
+} // Catch
+
+// end catch_interfaces_enum_values_registry.h
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+#include <string_view>
+#endif
+
+#ifdef __OBJC__
+// start catch_objc_arc.hpp
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+    [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+    if( [obj respondsToSelector: sel] )
+        return [obj performSelector: sel];
+    return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+    if( [obj respondsToSelector: sel] )
+        return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+    return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+// end catch_objc_arc.hpp
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
+#endif
+
+namespace Catch {
+    namespace Detail {
+
+        extern const std::string unprintableString;
+
+        std::string rawMemoryToString( const void *object, std::size_t size );
+
+        template<typename T>
+        std::string rawMemoryToString( const T& object ) {
+          return rawMemoryToString( &object, sizeof(object) );
+        }
+
+        template<typename T>
+        class IsStreamInsertable {
+            template<typename Stream, typename U>
+            static auto test(int)
+                -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
+
+            template<typename, typename>
+            static auto test(...)->std::false_type;
+
+        public:
+            static const bool value = decltype(test<std::ostream, const T&>(0))::value;
+        };
+
+        template<typename E>
+        std::string convertUnknownEnumToString( E e );
+
+        template<typename T>
+        typename std::enable_if<
+            !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
+        std::string>::type convertUnstreamable( T const& ) {
+            return Detail::unprintableString;
+        }
+        template<typename T>
+        typename std::enable_if<
+            !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
+         std::string>::type convertUnstreamable(T const& ex) {
+            return ex.what();
+        }
+
+        template<typename T>
+        typename std::enable_if<
+            std::is_enum<T>::value
+        , std::string>::type convertUnstreamable( T const& value ) {
+            return convertUnknownEnumToString( value );
+        }
+
+#if defined(_MANAGED)
+        //! Convert a CLR string to a utf8 std::string
+        template<typename T>
+        std::string clrReferenceToString( T^ ref ) {
+            if (ref == nullptr)
+                return std::string("null");
+            auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
+            cli::pin_ptr<System::Byte> p = &bytes[0];
+            return std::string(reinterpret_cast<char const *>(p), bytes->Length);
+        }
+#endif
+
+    } // namespace Detail
+
+    // If we decide for C++14, change these to enable_if_ts
+    template <typename T, typename = void>
+    struct StringMaker {
+        template <typename Fake = T>
+        static
+        typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
+            convert(const Fake& value) {
+                ReusableStringStream rss;
+                // NB: call using the function-like syntax to avoid ambiguity with
+                // user-defined templated operator<< under clang.
+                rss.operator<<(value);
+                return rss.str();
+        }
+
+        template <typename Fake = T>
+        static
+        typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
+            convert( const Fake& value ) {
+#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
+            return Detail::convertUnstreamable(value);
+#else
+            return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
+#endif
+        }
+    };
+
+    namespace Detail {
+
+        // This function dispatches all stringification requests inside of Catch.
+        // Should be preferably called fully qualified, like ::Catch::Detail::stringify
+        template <typename T>
+        std::string stringify(const T& e) {
+            return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
+        }
+
+        template<typename E>
+        std::string convertUnknownEnumToString( E e ) {
+            return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
+        }
+
+#if defined(_MANAGED)
+        template <typename T>
+        std::string stringify( T^ e ) {
+            return ::Catch::StringMaker<T^>::convert(e);
+        }
+#endif
+
+    } // namespace Detail
+
+    // Some predefined specializations
+
+    template<>
+    struct StringMaker<std::string> {
+        static std::string convert(const std::string& str);
+    };
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+    template<>
+    struct StringMaker<std::string_view> {
+        static std::string convert(std::string_view str);
+    };
+#endif
+
+    template<>
+    struct StringMaker<char const *> {
+        static std::string convert(char const * str);
+    };
+    template<>
+    struct StringMaker<char *> {
+        static std::string convert(char * str);
+    };
+
+#ifdef CATCH_CONFIG_WCHAR
+    template<>
+    struct StringMaker<std::wstring> {
+        static std::string convert(const std::wstring& wstr);
+    };
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+    template<>
+    struct StringMaker<std::wstring_view> {
+        static std::string convert(std::wstring_view str);
+    };
+# endif
+
+    template<>
+    struct StringMaker<wchar_t const *> {
+        static std::string convert(wchar_t const * str);
+    };
+    template<>
+    struct StringMaker<wchar_t *> {
+        static std::string convert(wchar_t * str);
+    };
+#endif
+
+    // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
+    //      while keeping string semantics?
+    template<int SZ>
+    struct StringMaker<char[SZ]> {
+        static std::string convert(char const* str) {
+            return ::Catch::Detail::stringify(std::string{ str });
+        }
+    };
+    template<int SZ>
+    struct StringMaker<signed char[SZ]> {
+        static std::string convert(signed char const* str) {
+            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
+        }
+    };
+    template<int SZ>
+    struct StringMaker<unsigned char[SZ]> {
+        static std::string convert(unsigned char const* str) {
+            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
+        }
+    };
+
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+    template<>
+    struct StringMaker<std::byte> {
+        static std::string convert(std::byte value);
+    };
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
+    template<>
+    struct StringMaker<int> {
+        static std::string convert(int value);
+    };
+    template<>
+    struct StringMaker<long> {
+        static std::string convert(long value);
+    };
+    template<>
+    struct StringMaker<long long> {
+        static std::string convert(long long value);
+    };
+    template<>
+    struct StringMaker<unsigned int> {
+        static std::string convert(unsigned int value);
+    };
+    template<>
+    struct StringMaker<unsigned long> {
+        static std::string convert(unsigned long value);
+    };
+    template<>
+    struct StringMaker<unsigned long long> {
+        static std::string convert(unsigned long long value);
+    };
+
+    template<>
+    struct StringMaker<bool> {
+        static std::string convert(bool b);
+    };
+
+    template<>
+    struct StringMaker<char> {
+        static std::string convert(char c);
+    };
+    template<>
+    struct StringMaker<signed char> {
+        static std::string convert(signed char c);
+    };
+    template<>
+    struct StringMaker<unsigned char> {
+        static std::string convert(unsigned char c);
+    };
+
+    template<>
+    struct StringMaker<std::nullptr_t> {
+        static std::string convert(std::nullptr_t);
+    };
+
+    template<>
+    struct StringMaker<float> {
+        static std::string convert(float value);
+        static int precision;
+    };
+
+    template<>
+    struct StringMaker<double> {
+        static std::string convert(double value);
+        static int precision;
+    };
+
+    template <typename T>
+    struct StringMaker<T*> {
+        template <typename U>
+        static std::string convert(U* p) {
+            if (p) {
+                return ::Catch::Detail::rawMemoryToString(p);
+            } else {
+                return "nullptr";
+            }
+        }
+    };
+
+    template <typename R, typename C>
+    struct StringMaker<R C::*> {
+        static std::string convert(R C::* p) {
+            if (p) {
+                return ::Catch::Detail::rawMemoryToString(p);
+            } else {
+                return "nullptr";
+            }
+        }
+    };
+
+#if defined(_MANAGED)
+    template <typename T>
+    struct StringMaker<T^> {
+        static std::string convert( T^ ref ) {
+            return ::Catch::Detail::clrReferenceToString(ref);
+        }
+    };
+#endif
+
+    namespace Detail {
+        template<typename InputIterator, typename Sentinel = InputIterator>
+        std::string rangeToString(InputIterator first, Sentinel last) {
+            ReusableStringStream rss;
+            rss << "{ ";
+            if (first != last) {
+                rss << ::Catch::Detail::stringify(*first);
+                for (++first; first != last; ++first)
+                    rss << ", " << ::Catch::Detail::stringify(*first);
+            }
+            rss << " }";
+            return rss.str();
+        }
+    }
+
+#ifdef __OBJC__
+    template<>
+    struct StringMaker<NSString*> {
+        static std::string convert(NSString * nsstring) {
+            if (!nsstring)
+                return "nil";
+            return std::string("@") + [nsstring UTF8String];
+        }
+    };
+    template<>
+    struct StringMaker<NSObject*> {
+        static std::string convert(NSObject* nsObject) {
+            return ::Catch::Detail::stringify([nsObject description]);
+        }
+
+    };
+    namespace Detail {
+        inline std::string stringify( NSString* nsstring ) {
+            return StringMaker<NSString*>::convert( nsstring );
+        }
+
+    } // namespace Detail
+#endif // __OBJC__
+
+} // namespace Catch
+
+//////////////////////////////////////////////////////
+// Separate std-lib types stringification, so it can be selectively enabled
+// This means that we do not bring in
+
+#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
+#  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
+#endif
+
+// Separate std::pair specialization
+#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
+#include <utility>
+namespace Catch {
+    template<typename T1, typename T2>
+    struct StringMaker<std::pair<T1, T2> > {
+        static std::string convert(const std::pair<T1, T2>& pair) {
+            ReusableStringStream rss;
+            rss << "{ "
+                << ::Catch::Detail::stringify(pair.first)
+                << ", "
+                << ::Catch::Detail::stringify(pair.second)
+                << " }";
+            return rss.str();
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
+
+#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
+#include <optional>
+namespace Catch {
+    template<typename T>
+    struct StringMaker<std::optional<T> > {
+        static std::string convert(const std::optional<T>& optional) {
+            ReusableStringStream rss;
+            if (optional.has_value()) {
+                rss << ::Catch::Detail::stringify(*optional);
+            } else {
+                rss << "{ }";
+            }
+            return rss.str();
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
+
+// Separate std::tuple specialization
+#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
+#include <tuple>
+namespace Catch {
+    namespace Detail {
+        template<
+            typename Tuple,
+            std::size_t N = 0,
+            bool = (N < std::tuple_size<Tuple>::value)
+            >
+            struct TupleElementPrinter {
+            static void print(const Tuple& tuple, std::ostream& os) {
+                os << (N ? ", " : " ")
+                    << ::Catch::Detail::stringify(std::get<N>(tuple));
+                TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
+            }
+        };
+
+        template<
+            typename Tuple,
+            std::size_t N
+        >
+            struct TupleElementPrinter<Tuple, N, false> {
+            static void print(const Tuple&, std::ostream&) {}
+        };
+
+    }
+
+    template<typename ...Types>
+    struct StringMaker<std::tuple<Types...>> {
+        static std::string convert(const std::tuple<Types...>& tuple) {
+            ReusableStringStream rss;
+            rss << '{';
+            Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
+            rss << " }";
+            return rss.str();
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+
+#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
+#include <variant>
+namespace Catch {
+    template<>
+    struct StringMaker<std::monostate> {
+        static std::string convert(const std::monostate&) {
+            return "{ }";
+        }
+    };
+
+    template<typename... Elements>
+    struct StringMaker<std::variant<Elements...>> {
+        static std::string convert(const std::variant<Elements...>& variant) {
+            if (variant.valueless_by_exception()) {
+                return "{valueless variant}";
+            } else {
+                return std::visit(
+                    [](const auto& value) {
+                        return ::Catch::Detail::stringify(value);
+                    },
+                    variant
+                );
+            }
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+
+namespace Catch {
+    // Import begin/ end from std here
+    using std::begin;
+    using std::end;
+
+    namespace detail {
+        template <typename...>
+        struct void_type {
+            using type = void;
+        };
+
+        template <typename T, typename = void>
+        struct is_range_impl : std::false_type {
+        };
+
+        template <typename T>
+        struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {
+        };
+    } // namespace detail
+
+    template <typename T>
+    struct is_range : detail::is_range_impl<T> {
+    };
+
+#if defined(_MANAGED) // Managed types are never ranges
+    template <typename T>
+    struct is_range<T^> {
+        static const bool value = false;
+    };
+#endif
+
+    template<typename Range>
+    std::string rangeToString( Range const& range ) {
+        return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
+    }
+
+    // Handle vector<bool> specially
+    template<typename Allocator>
+    std::string rangeToString( std::vector<bool, Allocator> const& v ) {
+        ReusableStringStream rss;
+        rss << "{ ";
+        bool first = true;
+        for( bool b : v ) {
+            if( first )
+                first = false;
+            else
+                rss << ", ";
+            rss << ::Catch::Detail::stringify( b );
+        }
+        rss << " }";
+        return rss.str();
+    }
+
+    template<typename R>
+    struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
+        static std::string convert( R const& range ) {
+            return rangeToString( range );
+        }
+    };
+
+    template <typename T, int SZ>
+    struct StringMaker<T[SZ]> {
+        static std::string convert(T const(&arr)[SZ]) {
+            return rangeToString(arr);
+        }
+    };
+
+} // namespace Catch
+
+// Separate std::chrono::duration specialization
+#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#include <ctime>
+#include <ratio>
+#include <chrono>
+
+namespace Catch {
+
+template <class Ratio>
+struct ratio_string {
+    static std::string symbol();
+};
+
+template <class Ratio>
+std::string ratio_string<Ratio>::symbol() {
+    Catch::ReusableStringStream rss;
+    rss << '[' << Ratio::num << '/'
+        << Ratio::den << ']';
+    return rss.str();
+}
+template <>
+struct ratio_string<std::atto> {
+    static std::string symbol();
+};
+template <>
+struct ratio_string<std::femto> {
+    static std::string symbol();
+};
+template <>
+struct ratio_string<std::pico> {
+    static std::string symbol();
+};
+template <>
+struct ratio_string<std::nano> {
+    static std::string symbol();
+};
+template <>
+struct ratio_string<std::micro> {
+    static std::string symbol();
+};
+template <>
+struct ratio_string<std::milli> {
+    static std::string symbol();
+};
+
+    ////////////
+    // std::chrono::duration specializations
+    template<typename Value, typename Ratio>
+    struct StringMaker<std::chrono::duration<Value, Ratio>> {
+        static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
+            ReusableStringStream rss;
+            rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
+            return rss.str();
+        }
+    };
+    template<typename Value>
+    struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
+        static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
+            ReusableStringStream rss;
+            rss << duration.count() << " s";
+            return rss.str();
+        }
+    };
+    template<typename Value>
+    struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
+        static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
+            ReusableStringStream rss;
+            rss << duration.count() << " m";
+            return rss.str();
+        }
+    };
+    template<typename Value>
+    struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
+        static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
+            ReusableStringStream rss;
+            rss << duration.count() << " h";
+            return rss.str();
+        }
+    };
+
+    ////////////
+    // std::chrono::time_point specialization
+    // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
+    template<typename Clock, typename Duration>
+    struct StringMaker<std::chrono::time_point<Clock, Duration>> {
+        static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
+            return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
+        }
+    };
+    // std::chrono::time_point<system_clock> specialization
+    template<typename Duration>
+    struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
+        static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
+            auto converted = std::chrono::system_clock::to_time_t(time_point);
+
+#ifdef _MSC_VER
+            std::tm timeInfo = {};
+            gmtime_s(&timeInfo, &converted);
+#else
+            std::tm* timeInfo = std::gmtime(&converted);
+#endif
+
+            auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
+            char timeStamp[timeStampSize];
+            const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
+
+#ifdef _MSC_VER
+            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
+#else
+            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
+#endif
+            return std::string(timeStamp);
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+
+#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
+namespace Catch { \
+    template<> struct StringMaker<enumName> { \
+        static std::string convert( enumName value ) { \
+            static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
+            return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
+        } \
+    }; \
+}
+
+#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// end catch_tostring.h
+#include <iosfwd>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#pragma warning(disable:4018) // more "signed/unsigned mismatch"
+#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
+#pragma warning(disable:4180) // qualifier applied to function type has no meaning
+#pragma warning(disable:4800) // Forcing result to true or false
+#endif
+
+namespace Catch {
+
+    struct ITransientExpression {
+        auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
+        auto getResult() const -> bool { return m_result; }
+        virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
+
+        ITransientExpression( bool isBinaryExpression, bool result )
+        :   m_isBinaryExpression( isBinaryExpression ),
+            m_result( result )
+        {}
+
+        // We don't actually need a virtual destructor, but many static analysers
+        // complain if it's not here :-(
+        virtual ~ITransientExpression();
+
+        bool m_isBinaryExpression;
+        bool m_result;
+
+    };
+
+    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
+
+    template<typename LhsT, typename RhsT>
+    class BinaryExpr  : public ITransientExpression {
+        LhsT m_lhs;
+        StringRef m_op;
+        RhsT m_rhs;
+
+        void streamReconstructedExpression( std::ostream &os ) const override {
+            formatReconstructedExpression
+                    ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
+        }
+
+    public:
+        BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
+        :   ITransientExpression{ true, comparisonResult },
+            m_lhs( lhs ),
+            m_op( op ),
+            m_rhs( rhs )
+        {}
+
+        template<typename T>
+        auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename T>
+        auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename T>
+        auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename T>
+        auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename T>
+        auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename T>
+        auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename T>
+        auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename T>
+        auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<T>::value,
+            "chained comparisons are not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+    };
+
+    template<typename LhsT>
+    class UnaryExpr : public ITransientExpression {
+        LhsT m_lhs;
+
+        void streamReconstructedExpression( std::ostream &os ) const override {
+            os << Catch::Detail::stringify( m_lhs );
+        }
+
+    public:
+        explicit UnaryExpr( LhsT lhs )
+        :   ITransientExpression{ false, static_cast<bool>(lhs) },
+            m_lhs( lhs )
+        {}
+    };
+
+    // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
+    template<typename LhsT, typename RhsT>
+    auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
+    template<typename T>
+    auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
+    template<typename T>
+    auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
+    template<typename T>
+    auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
+    template<typename T>
+    auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
+
+    template<typename LhsT, typename RhsT>
+    auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
+    template<typename T>
+    auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
+    template<typename T>
+    auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
+    template<typename T>
+    auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
+    template<typename T>
+    auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
+
+    template<typename LhsT>
+    class ExprLhs {
+        LhsT m_lhs;
+    public:
+        explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
+
+        template<typename RhsT>
+        auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
+        }
+        auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
+            return { m_lhs == rhs, m_lhs, "==", rhs };
+        }
+
+        template<typename RhsT>
+        auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
+        }
+        auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
+            return { m_lhs != rhs, m_lhs, "!=", rhs };
+        }
+
+        template<typename RhsT>
+        auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
+        }
+        template<typename RhsT>
+        auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
+        }
+        template<typename RhsT>
+        auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
+        }
+        template<typename RhsT>
+        auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
+        }
+        template <typename RhsT>
+        auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs };
+        }
+        template <typename RhsT>
+        auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs };
+        }
+        template <typename RhsT>
+        auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
+            return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs };
+        }
+
+        template<typename RhsT>
+        auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<RhsT>::value,
+            "operator&& is not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        template<typename RhsT>
+        auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
+            static_assert(always_false<RhsT>::value,
+            "operator|| is not supported inside assertions, "
+            "wrap the expression inside parentheses, or decompose it");
+        }
+
+        auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
+            return UnaryExpr<LhsT>{ m_lhs };
+        }
+    };
+
+    void handleExpression( ITransientExpression const& expr );
+
+    template<typename T>
+    void handleExpression( ExprLhs<T> const& expr ) {
+        handleExpression( expr.makeUnaryExpr() );
+    }
+
+    struct Decomposer {
+        template<typename T>
+        auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
+            return ExprLhs<T const&>{ lhs };
+        }
+
+        auto operator <=( bool value ) -> ExprLhs<bool> {
+            return ExprLhs<bool>{ value };
+        }
+    };
+
+} // end namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// end catch_decomposer.h
+// start catch_interfaces_capture.h
+
+#include <string>
+#include <chrono>
+
+namespace Catch {
+
+    class AssertionResult;
+    struct AssertionInfo;
+    struct SectionInfo;
+    struct SectionEndInfo;
+    struct MessageInfo;
+    struct MessageBuilder;
+    struct Counts;
+    struct AssertionReaction;
+    struct SourceLineInfo;
+
+    struct ITransientExpression;
+    struct IGeneratorTracker;
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    struct BenchmarkInfo;
+    template <typename Duration = std::chrono::duration<double, std::nano>>
+    struct BenchmarkStats;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+    struct IResultCapture {
+
+        virtual ~IResultCapture();
+
+        virtual bool sectionStarted(    SectionInfo const& sectionInfo,
+                                        Counts& assertions ) = 0;
+        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+
+        virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        virtual void benchmarkPreparing( std::string const& name ) = 0;
+        virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
+        virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
+        virtual void benchmarkFailed( std::string const& error ) = 0;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+        virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+        virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+        virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
+
+        virtual void handleFatalErrorCondition( StringRef message ) = 0;
+
+        virtual void handleExpr
+                (   AssertionInfo const& info,
+                    ITransientExpression const& expr,
+                    AssertionReaction& reaction ) = 0;
+        virtual void handleMessage
+                (   AssertionInfo const& info,
+                    ResultWas::OfType resultType,
+                    StringRef const& message,
+                    AssertionReaction& reaction ) = 0;
+        virtual void handleUnexpectedExceptionNotThrown
+                (   AssertionInfo const& info,
+                    AssertionReaction& reaction ) = 0;
+        virtual void handleUnexpectedInflightException
+                (   AssertionInfo const& info,
+                    std::string const& message,
+                    AssertionReaction& reaction ) = 0;
+        virtual void handleIncomplete
+                (   AssertionInfo const& info ) = 0;
+        virtual void handleNonExpr
+                (   AssertionInfo const &info,
+                    ResultWas::OfType resultType,
+                    AssertionReaction &reaction ) = 0;
+
+        virtual bool lastAssertionPassed() = 0;
+        virtual void assertionPassed() = 0;
+
+        // Deprecated, do not use:
+        virtual std::string getCurrentTestName() const = 0;
+        virtual const AssertionResult* getLastResult() const = 0;
+        virtual void exceptionEarlyReported() = 0;
+    };
+
+    IResultCapture& getResultCapture();
+}
+
+// end catch_interfaces_capture.h
+namespace Catch {
+
+    struct TestFailureException{};
+    struct AssertionResultData;
+    struct IResultCapture;
+    class RunContext;
+
+    class LazyExpression {
+        friend class AssertionHandler;
+        friend struct AssertionStats;
+        friend class RunContext;
+
+        ITransientExpression const* m_transientExpression = nullptr;
+        bool m_isNegated;
+    public:
+        LazyExpression( bool isNegated );
+        LazyExpression( LazyExpression const& other );
+        LazyExpression& operator = ( LazyExpression const& ) = delete;
+
+        explicit operator bool() const;
+
+        friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
+    };
+
+    struct AssertionReaction {
+        bool shouldDebugBreak = false;
+        bool shouldThrow = false;
+    };
+
+    class AssertionHandler {
+        AssertionInfo m_assertionInfo;
+        AssertionReaction m_reaction;
+        bool m_completed = false;
+        IResultCapture& m_resultCapture;
+
+    public:
+        AssertionHandler
+            (   StringRef const& macroName,
+                SourceLineInfo const& lineInfo,
+                StringRef capturedExpression,
+                ResultDisposition::Flags resultDisposition );
+        ~AssertionHandler() {
+            if ( !m_completed ) {
+                m_resultCapture.handleIncomplete( m_assertionInfo );
+            }
+        }
+
+        template<typename T>
+        void handleExpr( ExprLhs<T> const& expr ) {
+            handleExpr( expr.makeUnaryExpr() );
+        }
+        void handleExpr( ITransientExpression const& expr );
+
+        void handleMessage(ResultWas::OfType resultType, StringRef const& message);
+
+        void handleExceptionThrownAsExpected();
+        void handleUnexpectedExceptionNotThrown();
+        void handleExceptionNotThrownAsExpected();
+        void handleThrowingCallSkipped();
+        void handleUnexpectedInflightException();
+
+        void complete();
+        void setCompleted();
+
+        // query
+        auto allowThrows() const -> bool;
+    };
+
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
+
+} // namespace Catch
+
+// end catch_assertionhandler.h
+// start catch_message.h
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+    struct MessageInfo {
+        MessageInfo(    StringRef const& _macroName,
+                        SourceLineInfo const& _lineInfo,
+                        ResultWas::OfType _type );
+
+        StringRef macroName;
+        std::string message;
+        SourceLineInfo lineInfo;
+        ResultWas::OfType type;
+        unsigned int sequence;
+
+        bool operator == ( MessageInfo const& other ) const;
+        bool operator < ( MessageInfo const& other ) const;
+    private:
+        static unsigned int globalCount;
+    };
+
+    struct MessageStream {
+
+        template<typename T>
+        MessageStream& operator << ( T const& value ) {
+            m_stream << value;
+            return *this;
+        }
+
+        ReusableStringStream m_stream;
+    };
+
+    struct MessageBuilder : MessageStream {
+        MessageBuilder( StringRef const& macroName,
+                        SourceLineInfo const& lineInfo,
+                        ResultWas::OfType type );
+
+        template<typename T>
+        MessageBuilder& operator << ( T const& value ) {
+            m_stream << value;
+            return *this;
+        }
+
+        MessageInfo m_info;
+    };
+
+    class ScopedMessage {
+    public:
+        explicit ScopedMessage( MessageBuilder const& builder );
+        ScopedMessage( ScopedMessage& duplicate ) = delete;
+        ScopedMessage( ScopedMessage&& old );
+        ~ScopedMessage();
+
+        MessageInfo m_info;
+        bool m_moved;
+    };
+
+    class Capturer {
+        std::vector<MessageInfo> m_messages;
+        IResultCapture& m_resultCapture = getResultCapture();
+        size_t m_captured = 0;
+    public:
+        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
+        ~Capturer();
+
+        void captureValue( size_t index, std::string const& value );
+
+        template<typename T>
+        void captureValues( size_t index, T const& value ) {
+            captureValue( index, Catch::Detail::stringify( value ) );
+        }
+
+        template<typename T, typename... Ts>
+        void captureValues( size_t index, T const& value, Ts const&... values ) {
+            captureValue( index, Catch::Detail::stringify(value) );
+            captureValues( index+1, values... );
+        }
+    };
+
+} // end namespace Catch
+
+// end catch_message.h
+#if !defined(CATCH_CONFIG_DISABLE)
+
+#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
+  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
+#else
+  #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
+#endif
+
+#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+
+///////////////////////////////////////////////////////////////////////////////
+// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
+// macros.
+#define INTERNAL_CATCH_TRY
+#define INTERNAL_CATCH_CATCH( capturer )
+
+#else // CATCH_CONFIG_FAST_COMPILE
+
+#define INTERNAL_CATCH_TRY try
+#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
+
+#endif
+
+#define INTERNAL_CATCH_REACT( handler ) handler.complete();
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
+    do { \
+        CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        INTERNAL_CATCH_TRY { \
+            CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+            catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
+            CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
+    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
+    if( Catch::getResultCapture().lastAssertionPassed() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
+    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
+    if( !Catch::getResultCapture().lastAssertionPassed() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
+    do { \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        try { \
+            static_cast<void>(__VA_ARGS__); \
+            catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
+        } \
+        catch( ... ) { \
+            catchAssertionHandler.handleUnexpectedInflightException(); \
+        } \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
+    do { \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
+        if( catchAssertionHandler.allowThrows() ) \
+            try { \
+                static_cast<void>(__VA_ARGS__); \
+                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+            } \
+            catch( ... ) { \
+                catchAssertionHandler.handleExceptionThrownAsExpected(); \
+            } \
+        else \
+            catchAssertionHandler.handleThrowingCallSkipped(); \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
+    do { \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
+        if( catchAssertionHandler.allowThrows() ) \
+            try { \
+                static_cast<void>(expr); \
+                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+            } \
+            catch( exceptionType const& ) { \
+                catchAssertionHandler.handleExceptionThrownAsExpected(); \
+            } \
+            catch( ... ) { \
+                catchAssertionHandler.handleUnexpectedInflightException(); \
+            } \
+        else \
+            catchAssertionHandler.handleThrowingCallSkipped(); \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
+    do { \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
+        catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
+    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
+    varName.captureValues( 0, __VA_ARGS__ )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( macroName, log ) \
+    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
+    Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
+
+///////////////////////////////////////////////////////////////////////////////
+// Although this is matcher-based, it can be used with just a string
+#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
+    do { \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        if( catchAssertionHandler.allowThrows() ) \
+            try { \
+                static_cast<void>(__VA_ARGS__); \
+                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+            } \
+            catch( ... ) { \
+                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
+            } \
+        else \
+            catchAssertionHandler.handleThrowingCallSkipped(); \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( false )
+
+#endif // CATCH_CONFIG_DISABLE
+
+// end catch_capture.hpp
+// start catch_section.h
+
+// start catch_section_info.h
+
+// start catch_totals.h
+
+#include <cstddef>
+
+namespace Catch {
+
+    struct Counts {
+        Counts operator - ( Counts const& other ) const;
+        Counts& operator += ( Counts const& other );
+
+        std::size_t total() const;
+        bool allPassed() const;
+        bool allOk() const;
+
+        std::size_t passed = 0;
+        std::size_t failed = 0;
+        std::size_t failedButOk = 0;
+    };
+
+    struct Totals {
+
+        Totals operator - ( Totals const& other ) const;
+        Totals& operator += ( Totals const& other );
+
+        Totals delta( Totals const& prevTotals ) const;
+
+        int error = 0;
+        Counts assertions;
+        Counts testCases;
+    };
+}
+
+// end catch_totals.h
+#include <string>
+
+namespace Catch {
+
+    struct SectionInfo {
+        SectionInfo
+            (   SourceLineInfo const& _lineInfo,
+                std::string const& _name );
+
+        // Deprecated
+        SectionInfo
+            (   SourceLineInfo const& _lineInfo,
+                std::string const& _name,
+                std::string const& ) : SectionInfo( _lineInfo, _name ) {}
+
+        std::string name;
+        std::string description; // !Deprecated: this will always be empty
+        SourceLineInfo lineInfo;
+    };
+
+    struct SectionEndInfo {
+        SectionInfo sectionInfo;
+        Counts prevAssertions;
+        double durationInSeconds;
+    };
+
+} // end namespace Catch
+
+// end catch_section_info.h
+// start catch_timer.h
+
+#include <cstdint>
+
+namespace Catch {
+
+    auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
+    auto getEstimatedClockResolution() -> uint64_t;
+
+    class Timer {
+        uint64_t m_nanoseconds = 0;
+    public:
+        void start();
+        auto getElapsedNanoseconds() const -> uint64_t;
+        auto getElapsedMicroseconds() const -> uint64_t;
+        auto getElapsedMilliseconds() const -> unsigned int;
+        auto getElapsedSeconds() const -> double;
+    };
+
+} // namespace Catch
+
+// end catch_timer.h
+#include <string>
+
+namespace Catch {
+
+    class Section : NonCopyable {
+    public:
+        Section( SectionInfo const& info );
+        ~Section();
+
+        // This indicates whether the section should be executed or not
+        explicit operator bool() const;
+
+    private:
+        SectionInfo m_info;
+
+        std::string m_name;
+        Counts m_assertions;
+        bool m_sectionIncluded;
+        Timer m_timer;
+    };
+
+} // end namespace Catch
+
+#define INTERNAL_CATCH_SECTION( ... ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+// end catch_section.h
+// start catch_interfaces_exception.h
+
+// start catch_interfaces_registry_hub.h
+
+#include <string>
+#include <memory>
+
+namespace Catch {
+
+    class TestCase;
+    struct ITestCaseRegistry;
+    struct IExceptionTranslatorRegistry;
+    struct IExceptionTranslator;
+    struct IReporterRegistry;
+    struct IReporterFactory;
+    struct ITagAliasRegistry;
+    struct IMutableEnumValuesRegistry;
+
+    class StartupExceptionRegistry;
+
+    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
+
+    struct IRegistryHub {
+        virtual ~IRegistryHub();
+
+        virtual IReporterRegistry const& getReporterRegistry() const = 0;
+        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+        virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
+        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
+
+        virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
+    };
+
+    struct IMutableRegistryHub {
+        virtual ~IMutableRegistryHub();
+        virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
+        virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
+        virtual void registerTest( TestCase const& testInfo ) = 0;
+        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+        virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
+        virtual void registerStartupException() noexcept = 0;
+        virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
+    };
+
+    IRegistryHub const& getRegistryHub();
+    IMutableRegistryHub& getMutableRegistryHub();
+    void cleanUp();
+    std::string translateActiveException();
+
+}
+
+// end catch_interfaces_registry_hub.h
+#if defined(CATCH_CONFIG_DISABLE)
+    #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
+        static std::string translatorName( signature )
+#endif
+
+#include <exception>
+#include <string>
+#include <vector>
+
+namespace Catch {
+    using exceptionTranslateFunction = std::string(*)();
+
+    struct IExceptionTranslator;
+    using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
+
+    struct IExceptionTranslator {
+        virtual ~IExceptionTranslator();
+        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
+    };
+
+    struct IExceptionTranslatorRegistry {
+        virtual ~IExceptionTranslatorRegistry();
+
+        virtual std::string translateActiveException() const = 0;
+    };
+
+    class ExceptionTranslatorRegistrar {
+        template<typename T>
+        class ExceptionTranslator : public IExceptionTranslator {
+        public:
+
+            ExceptionTranslator( std::string(*translateFunction)( T& ) )
+            : m_translateFunction( translateFunction )
+            {}
+
+            std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+                return "";
+#else
+                try {
+                    if( it == itEnd )
+                        std::rethrow_exception(std::current_exception());
+                    else
+                        return (*it)->translate( it+1, itEnd );
+                }
+                catch( T& ex ) {
+                    return m_translateFunction( ex );
+                }
+#endif
+            }
+
+        protected:
+            std::string(*m_translateFunction)( T& );
+        };
+
+    public:
+        template<typename T>
+        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+            getMutableRegistryHub().registerTranslator
+                ( new ExceptionTranslator<T>( translateFunction ) );
+        }
+    };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
+    static std::string translatorName( signature ); \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+    static std::string translatorName( signature )
+
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
+
+// end catch_interfaces_exception.h
+// start catch_approx.h
+
+#include <type_traits>
+
+namespace Catch {
+namespace Detail {
+
+    class Approx {
+    private:
+        bool equalityComparisonImpl(double other) const;
+        // Validates the new margin (margin >= 0)
+        // out-of-line to avoid including stdexcept in the header
+        void setMargin(double margin);
+        // Validates the new epsilon (0 < epsilon < 1)
+        // out-of-line to avoid including stdexcept in the header
+        void setEpsilon(double epsilon);
+
+    public:
+        explicit Approx ( double value );
+
+        static Approx custom();
+
+        Approx operator-() const;
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx operator()( T const& value ) const {
+            Approx approx( static_cast<double>(value) );
+            approx.m_epsilon = m_epsilon;
+            approx.m_margin = m_margin;
+            approx.m_scale = m_scale;
+            return approx;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        explicit Approx( T const& value ): Approx(static_cast<double>(value))
+        {}
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator == ( const T& lhs, Approx const& rhs ) {
+            auto lhs_v = static_cast<double>(lhs);
+            return rhs.equalityComparisonImpl(lhs_v);
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator == ( Approx const& lhs, const T& rhs ) {
+            return operator==( rhs, lhs );
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator != ( T const& lhs, Approx const& rhs ) {
+            return !operator==( lhs, rhs );
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator != ( Approx const& lhs, T const& rhs ) {
+            return !operator==( rhs, lhs );
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator <= ( T const& lhs, Approx const& rhs ) {
+            return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator <= ( Approx const& lhs, T const& rhs ) {
+            return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator >= ( T const& lhs, Approx const& rhs ) {
+            return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator >= ( Approx const& lhs, T const& rhs ) {
+            return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx& epsilon( T const& newEpsilon ) {
+            double epsilonAsDouble = static_cast<double>(newEpsilon);
+            setEpsilon(epsilonAsDouble);
+            return *this;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx& margin( T const& newMargin ) {
+            double marginAsDouble = static_cast<double>(newMargin);
+            setMargin(marginAsDouble);
+            return *this;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx& scale( T const& newScale ) {
+            m_scale = static_cast<double>(newScale);
+            return *this;
+        }
+
+        std::string toString() const;
+
+    private:
+        double m_epsilon;
+        double m_margin;
+        double m_scale;
+        double m_value;
+    };
+} // end namespace Detail
+
+namespace literals {
+    Detail::Approx operator "" _a(long double val);
+    Detail::Approx operator "" _a(unsigned long long val);
+} // end namespace literals
+
+template<>
+struct StringMaker<Catch::Detail::Approx> {
+    static std::string convert(Catch::Detail::Approx const& value);
+};
+
+} // end namespace Catch
+
+// end catch_approx.h
+// start catch_string_manip.h
+
+#include <string>
+#include <iosfwd>
+#include <vector>
+
+namespace Catch {
+
+    bool startsWith( std::string const& s, std::string const& prefix );
+    bool startsWith( std::string const& s, char prefix );
+    bool endsWith( std::string const& s, std::string const& suffix );
+    bool endsWith( std::string const& s, char suffix );
+    bool contains( std::string const& s, std::string const& infix );
+    void toLowerInPlace( std::string& s );
+    std::string toLower( std::string const& s );
+    //! Returns a new string without whitespace at the start/end
+    std::string trim( std::string const& str );
+    //! Returns a substring of the original ref without whitespace. Beware lifetimes!
+    StringRef trim(StringRef ref);
+
+    // !!! Be aware, returns refs into original string - make sure original string outlives them
+    std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
+    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+    struct pluralise {
+        pluralise( std::size_t count, std::string const& label );
+
+        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+        std::size_t m_count;
+        std::string m_label;
+    };
+}
+
+// end catch_string_manip.h
+#ifndef CATCH_CONFIG_DISABLE_MATCHERS
+// start catch_capture_matchers.h
+
+// start catch_matchers.h
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+namespace Matchers {
+    namespace Impl {
+
+        template<typename ArgT> struct MatchAllOf;
+        template<typename ArgT> struct MatchAnyOf;
+        template<typename ArgT> struct MatchNotOf;
+
+        class MatcherUntypedBase {
+        public:
+            MatcherUntypedBase() = default;
+            MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
+            MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
+            std::string toString() const;
+
+        protected:
+            virtual ~MatcherUntypedBase();
+            virtual std::string describe() const = 0;
+            mutable std::string m_cachedToString;
+        };
+
+#ifdef __clang__
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+
+        template<typename ObjectT>
+        struct MatcherMethod {
+            virtual bool match( ObjectT const& arg ) const = 0;
+        };
+
+#if defined(__OBJC__)
+        // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
+        // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
+        template<>
+        struct MatcherMethod<NSString*> {
+            virtual bool match( NSString* arg ) const = 0;
+        };
+#endif
+
+#ifdef __clang__
+#    pragma clang diagnostic pop
+#endif
+
+        template<typename T>
+        struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
+
+            MatchAllOf<T> operator && ( MatcherBase const& other ) const;
+            MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
+            MatchNotOf<T> operator ! () const;
+        };
+
+        template<typename ArgT>
+        struct MatchAllOf : MatcherBase<ArgT> {
+            bool match( ArgT const& arg ) const override {
+                for( auto matcher : m_matchers ) {
+                    if (!matcher->match(arg))
+                        return false;
+                }
+                return true;
+            }
+            std::string describe() const override {
+                std::string description;
+                description.reserve( 4 + m_matchers.size()*32 );
+                description += "( ";
+                bool first = true;
+                for( auto matcher : m_matchers ) {
+                    if( first )
+                        first = false;
+                    else
+                        description += " and ";
+                    description += matcher->toString();
+                }
+                description += " )";
+                return description;
+            }
+
+            MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
+                auto copy(*this);
+                copy.m_matchers.push_back( &other );
+                return copy;
+            }
+
+            std::vector<MatcherBase<ArgT> const*> m_matchers;
+        };
+        template<typename ArgT>
+        struct MatchAnyOf : MatcherBase<ArgT> {
+
+            bool match( ArgT const& arg ) const override {
+                for( auto matcher : m_matchers ) {
+                    if (matcher->match(arg))
+                        return true;
+                }
+                return false;
+            }
+            std::string describe() const override {
+                std::string description;
+                description.reserve( 4 + m_matchers.size()*32 );
+                description += "( ";
+                bool first = true;
+                for( auto matcher : m_matchers ) {
+                    if( first )
+                        first = false;
+                    else
+                        description += " or ";
+                    description += matcher->toString();
+                }
+                description += " )";
+                return description;
+            }
+
+            MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
+                auto copy(*this);
+                copy.m_matchers.push_back( &other );
+                return copy;
+            }
+
+            std::vector<MatcherBase<ArgT> const*> m_matchers;
+        };
+
+        template<typename ArgT>
+        struct MatchNotOf : MatcherBase<ArgT> {
+
+            MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
+
+            bool match( ArgT const& arg ) const override {
+                return !m_underlyingMatcher.match( arg );
+            }
+
+            std::string describe() const override {
+                return "not " + m_underlyingMatcher.toString();
+            }
+            MatcherBase<ArgT> const& m_underlyingMatcher;
+        };
+
+        template<typename T>
+        MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
+            return MatchAllOf<T>() && *this && other;
+        }
+        template<typename T>
+        MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
+            return MatchAnyOf<T>() || *this || other;
+        }
+        template<typename T>
+        MatchNotOf<T> MatcherBase<T>::operator ! () const {
+            return MatchNotOf<T>( *this );
+        }
+
+    } // namespace Impl
+
+} // namespace Matchers
+
+using namespace Matchers;
+using Matchers::Impl::MatcherBase;
+
+} // namespace Catch
+
+// end catch_matchers.h
+// start catch_matchers_exception.hpp
+
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+class ExceptionMessageMatcher : public MatcherBase<std::exception> {
+    std::string m_message;
+public:
+
+    ExceptionMessageMatcher(std::string const& message):
+        m_message(message)
+    {}
+
+    bool match(std::exception const& ex) const override;
+
+    std::string describe() const override;
+};
+
+} // namespace Exception
+
+Exception::ExceptionMessageMatcher Message(std::string const& message);
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_exception.hpp
+// start catch_matchers_floating.h
+
+namespace Catch {
+namespace Matchers {
+
+    namespace Floating {
+
+        enum class FloatingPointKind : uint8_t;
+
+        struct WithinAbsMatcher : MatcherBase<double> {
+            WithinAbsMatcher(double target, double margin);
+            bool match(double const& matchee) const override;
+            std::string describe() const override;
+        private:
+            double m_target;
+            double m_margin;
+        };
+
+        struct WithinUlpsMatcher : MatcherBase<double> {
+            WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
+            bool match(double const& matchee) const override;
+            std::string describe() const override;
+        private:
+            double m_target;
+            uint64_t m_ulps;
+            FloatingPointKind m_type;
+        };
+
+        // Given IEEE-754 format for floats and doubles, we can assume
+        // that float -> double promotion is lossless. Given this, we can
+        // assume that if we do the standard relative comparison of
+        // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
+        // the same result if we do this for floats, as if we do this for
+        // doubles that were promoted from floats.
+        struct WithinRelMatcher : MatcherBase<double> {
+            WithinRelMatcher(double target, double epsilon);
+            bool match(double const& matchee) const override;
+            std::string describe() const override;
+        private:
+            double m_target;
+            double m_epsilon;
+        };
+
+    } // namespace Floating
+
+    // The following functions create the actual matcher objects.
+    // This allows the types to be inferred
+    Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
+    Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
+    Floating::WithinAbsMatcher WithinAbs(double target, double margin);
+    Floating::WithinRelMatcher WithinRel(double target, double eps);
+    // defaults epsilon to 100*numeric_limits<double>::epsilon()
+    Floating::WithinRelMatcher WithinRel(double target);
+    Floating::WithinRelMatcher WithinRel(float target, float eps);
+    // defaults epsilon to 100*numeric_limits<float>::epsilon()
+    Floating::WithinRelMatcher WithinRel(float target);
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_floating.h
+// start catch_matchers_generic.hpp
+
+#include <functional>
+#include <string>
+
+namespace Catch {
+namespace Matchers {
+namespace Generic {
+
+namespace Detail {
+    std::string finalizeDescription(const std::string& desc);
+}
+
+template <typename T>
+class PredicateMatcher : public MatcherBase<T> {
+    std::function<bool(T const&)> m_predicate;
+    std::string m_description;
+public:
+
+    PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
+        :m_predicate(std::move(elem)),
+        m_description(Detail::finalizeDescription(descr))
+    {}
+
+    bool match( T const& item ) const override {
+        return m_predicate(item);
+    }
+
+    std::string describe() const override {
+        return m_description;
+    }
+};
+
+} // namespace Generic
+
+    // The following functions create the actual matcher objects.
+    // The user has to explicitly specify type to the function, because
+    // inferring std::function<bool(T const&)> is hard (but possible) and
+    // requires a lot of TMP.
+    template<typename T>
+    Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
+        return Generic::PredicateMatcher<T>(predicate, description);
+    }
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_generic.hpp
+// start catch_matchers_string.h
+
+#include <string>
+
+namespace Catch {
+namespace Matchers {
+
+    namespace StdString {
+
+        struct CasedString
+        {
+            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
+            std::string adjustString( std::string const& str ) const;
+            std::string caseSensitivitySuffix() const;
+
+            CaseSensitive::Choice m_caseSensitivity;
+            std::string m_str;
+        };
+
+        struct StringMatcherBase : MatcherBase<std::string> {
+            StringMatcherBase( std::string const& operation, CasedString const& comparator );
+            std::string describe() const override;
+
+            CasedString m_comparator;
+            std::string m_operation;
+        };
+
+        struct EqualsMatcher : StringMatcherBase {
+            EqualsMatcher( CasedString const& comparator );
+            bool match( std::string const& source ) const override;
+        };
+        struct ContainsMatcher : StringMatcherBase {
+            ContainsMatcher( CasedString const& comparator );
+            bool match( std::string const& source ) const override;
+        };
+        struct StartsWithMatcher : StringMatcherBase {
+            StartsWithMatcher( CasedString const& comparator );
+            bool match( std::string const& source ) const override;
+        };
+        struct EndsWithMatcher : StringMatcherBase {
+            EndsWithMatcher( CasedString const& comparator );
+            bool match( std::string const& source ) const override;
+        };
+
+        struct RegexMatcher : MatcherBase<std::string> {
+            RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
+            bool match( std::string const& matchee ) const override;
+            std::string describe() const override;
+
+        private:
+            std::string m_regex;
+            CaseSensitive::Choice m_caseSensitivity;
+        };
+
+    } // namespace StdString
+
+    // The following functions create the actual matcher objects.
+    // This allows the types to be inferred
+
+    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+    StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_string.h
+// start catch_matchers_vector.h
+
+#include <algorithm>
+
+namespace Catch {
+namespace Matchers {
+
+    namespace Vector {
+        template<typename T, typename Alloc>
+        struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
+
+            ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
+
+            bool match(std::vector<T, Alloc> const &v) const override {
+                for (auto const& el : v) {
+                    if (el == m_comparator) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            std::string describe() const override {
+                return "Contains: " + ::Catch::Detail::stringify( m_comparator );
+            }
+
+            T const& m_comparator;
+        };
+
+        template<typename T, typename AllocComp, typename AllocMatch>
+        struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
+
+            ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
+
+            bool match(std::vector<T, AllocMatch> const &v) const override {
+                // !TBD: see note in EqualsMatcher
+                if (m_comparator.size() > v.size())
+                    return false;
+                for (auto const& comparator : m_comparator) {
+                    auto present = false;
+                    for (const auto& el : v) {
+                        if (el == comparator) {
+                            present = true;
+                            break;
+                        }
+                    }
+                    if (!present) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+            std::string describe() const override {
+                return "Contains: " + ::Catch::Detail::stringify( m_comparator );
+            }
+
+            std::vector<T, AllocComp> const& m_comparator;
+        };
+
+        template<typename T, typename AllocComp, typename AllocMatch>
+        struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
+
+            EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
+
+            bool match(std::vector<T, AllocMatch> const &v) const override {
+                // !TBD: This currently works if all elements can be compared using !=
+                // - a more general approach would be via a compare template that defaults
+                // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
+                // - then just call that directly
+                if (m_comparator.size() != v.size())
+                    return false;
+                for (std::size_t i = 0; i < v.size(); ++i)
+                    if (m_comparator[i] != v[i])
+                        return false;
+                return true;
+            }
+            std::string describe() const override {
+                return "Equals: " + ::Catch::Detail::stringify( m_comparator );
+            }
+            std::vector<T, AllocComp> const& m_comparator;
+        };
+
+        template<typename T, typename AllocComp, typename AllocMatch>
+        struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
+
+            ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}
+
+            bool match(std::vector<T, AllocMatch> const &v) const override {
+                if (m_comparator.size() != v.size())
+                    return false;
+                for (std::size_t i = 0; i < v.size(); ++i)
+                    if (m_comparator[i] != approx(v[i]))
+                        return false;
+                return true;
+            }
+            std::string describe() const override {
+                return "is approx: " + ::Catch::Detail::stringify( m_comparator );
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& epsilon( T const& newEpsilon ) {
+                approx.epsilon(newEpsilon);
+                return *this;
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& margin( T const& newMargin ) {
+                approx.margin(newMargin);
+                return *this;
+            }
+            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+            ApproxMatcher& scale( T const& newScale ) {
+                approx.scale(newScale);
+                return *this;
+            }
+
+            std::vector<T, AllocComp> const& m_comparator;
+            mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
+        };
+
+        template<typename T, typename AllocComp, typename AllocMatch>
+        struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
+            UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
+            bool match(std::vector<T, AllocMatch> const& vec) const override {
+                if (m_target.size() != vec.size()) {
+                    return false;
+                }
+                return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
+            }
+
+            std::string describe() const override {
+                return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
+            }
+        private:
+            std::vector<T, AllocComp> const& m_target;
+        };
+
+    } // namespace Vector
+
+    // The following functions create the actual matcher objects.
+    // This allows the types to be inferred
+
+    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+    Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
+        return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );
+    }
+
+    template<typename T, typename Alloc = std::allocator<T>>
+    Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
+        return Vector::ContainsElementMatcher<T, Alloc>( comparator );
+    }
+
+    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+    Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
+        return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );
+    }
+
+    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+    Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
+        return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );
+    }
+
+    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+    Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
+        return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );
+    }
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_vector.h
+namespace Catch {
+
+    template<typename ArgT, typename MatcherT>
+    class MatchExpr : public ITransientExpression {
+        ArgT const& m_arg;
+        MatcherT m_matcher;
+        StringRef m_matcherString;
+    public:
+        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
+        :   ITransientExpression{ true, matcher.match( arg ) },
+            m_arg( arg ),
+            m_matcher( matcher ),
+            m_matcherString( matcherString )
+        {}
+
+        void streamReconstructedExpression( std::ostream &os ) const override {
+            auto matcherAsString = m_matcher.toString();
+            os << Catch::Detail::stringify( m_arg ) << ' ';
+            if( matcherAsString == Detail::unprintableString )
+                os << m_matcherString;
+            else
+                os << matcherAsString;
+        }
+    };
+
+    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
+
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
+
+    template<typename ArgT, typename MatcherT>
+    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
+        return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
+    }
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
+    do { \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        INTERNAL_CATCH_TRY { \
+            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
+        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( false )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
+    do { \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        if( catchAssertionHandler.allowThrows() ) \
+            try { \
+                static_cast<void>(__VA_ARGS__ ); \
+                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
+            } \
+            catch( exceptionType const& ex ) { \
+                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
+            } \
+            catch( ... ) { \
+                catchAssertionHandler.handleUnexpectedInflightException(); \
+            } \
+        else \
+            catchAssertionHandler.handleThrowingCallSkipped(); \
+        INTERNAL_CATCH_REACT( catchAssertionHandler ) \
+    } while( false )
+
+// end catch_capture_matchers.h
+#endif
+// start catch_generators.hpp
+
+// start catch_interfaces_generatortracker.h
+
+
+#include <memory>
+
+namespace Catch {
+
+    namespace Generators {
+        class GeneratorUntypedBase {
+        public:
+            GeneratorUntypedBase() = default;
+            virtual ~GeneratorUntypedBase();
+            // Attempts to move the generator to the next element
+             //
+             // Returns true iff the move succeeded (and a valid element
+             // can be retrieved).
+            virtual bool next() = 0;
+        };
+        using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
+
+    } // namespace Generators
+
+    struct IGeneratorTracker {
+        virtual ~IGeneratorTracker();
+        virtual auto hasGenerator() const -> bool = 0;
+        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
+        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
+    };
+
+} // namespace Catch
+
+// end catch_interfaces_generatortracker.h
+// start catch_enforce.h
+
+#include <exception>
+
+namespace Catch {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+    template <typename Ex>
+    [[noreturn]]
+    void throw_exception(Ex const& e) {
+        throw e;
+    }
+#else // ^^ Exceptions are enabled //  Exceptions are disabled vv
+    [[noreturn]]
+    void throw_exception(std::exception const& e);
+#endif
+
+    [[noreturn]]
+    void throw_logic_error(std::string const& msg);
+    [[noreturn]]
+    void throw_domain_error(std::string const& msg);
+    [[noreturn]]
+    void throw_runtime_error(std::string const& msg);
+
+} // namespace Catch;
+
+#define CATCH_MAKE_MSG(...) \
+    (Catch::ReusableStringStream() << __VA_ARGS__).str()
+
+#define CATCH_INTERNAL_ERROR(...) \
+    Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
+
+#define CATCH_ERROR(...) \
+    Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
+
+#define CATCH_RUNTIME_ERROR(...) \
+    Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
+
+#define CATCH_ENFORCE( condition, ... ) \
+    do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
+
+// end catch_enforce.h
+#include <memory>
+#include <vector>
+#include <cassert>
+
+#include <utility>
+#include <exception>
+
+namespace Catch {
+
+class GeneratorException : public std::exception {
+    const char* const m_msg = "";
+
+public:
+    GeneratorException(const char* msg):
+        m_msg(msg)
+    {}
+
+    const char* what() const noexcept override final;
+};
+
+namespace Generators {
+
+    // !TBD move this into its own location?
+    namespace pf{
+        template<typename T, typename... Args>
+        std::unique_ptr<T> make_unique( Args&&... args ) {
+            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+        }
+    }
+
+    template<typename T>
+    struct IGenerator : GeneratorUntypedBase {
+        virtual ~IGenerator() = default;
+
+        // Returns the current element of the generator
+        //
+        // \Precondition The generator is either freshly constructed,
+        // or the last call to `next()` returned true
+        virtual T const& get() const = 0;
+        using type = T;
+    };
+
+    template<typename T>
+    class SingleValueGenerator final : public IGenerator<T> {
+        T m_value;
+    public:
+        SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
+
+        T const& get() const override {
+            return m_value;
+        }
+        bool next() override {
+            return false;
+        }
+    };
+
+    template<typename T>
+    class FixedValuesGenerator final : public IGenerator<T> {
+        static_assert(!std::is_same<T, bool>::value,
+            "FixedValuesGenerator does not support bools because of std::vector<bool>"
+            "specialization, use SingleValue Generator instead.");
+        std::vector<T> m_values;
+        size_t m_idx = 0;
+    public:
+        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
+
+        T const& get() const override {
+            return m_values[m_idx];
+        }
+        bool next() override {
+            ++m_idx;
+            return m_idx < m_values.size();
+        }
+    };
+
+    template <typename T>
+    class GeneratorWrapper final {
+        std::unique_ptr<IGenerator<T>> m_generator;
+    public:
+        GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
+            m_generator(std::move(generator))
+        {}
+        T const& get() const {
+            return m_generator->get();
+        }
+        bool next() {
+            return m_generator->next();
+        }
+    };
+
+    template <typename T>
+    GeneratorWrapper<T> value(T&& value) {
+        return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
+    }
+    template <typename T>
+    GeneratorWrapper<T> values(std::initializer_list<T> values) {
+        return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
+    }
+
+    template<typename T>
+    class Generators : public IGenerator<T> {
+        std::vector<GeneratorWrapper<T>> m_generators;
+        size_t m_current = 0;
+
+        void populate(GeneratorWrapper<T>&& generator) {
+            m_generators.emplace_back(std::move(generator));
+        }
+        void populate(T&& val) {
+            m_generators.emplace_back(value(std::forward<T>(val)));
+        }
+        template<typename U>
+        void populate(U&& val) {
+            populate(T(std::forward<U>(val)));
+        }
+        template<typename U, typename... Gs>
+        void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
+            populate(std::forward<U>(valueOrGenerator));
+            populate(std::forward<Gs>(moreGenerators)...);
+        }
+
+    public:
+        template <typename... Gs>
+        Generators(Gs &&... moreGenerators) {
+            m_generators.reserve(sizeof...(Gs));
+            populate(std::forward<Gs>(moreGenerators)...);
+        }
+
+        T const& get() const override {
+            return m_generators[m_current].get();
+        }
+
+        bool next() override {
+            if (m_current >= m_generators.size()) {
+                return false;
+            }
+            const bool current_status = m_generators[m_current].next();
+            if (!current_status) {
+                ++m_current;
+            }
+            return m_current < m_generators.size();
+        }
+    };
+
+    template<typename... Ts>
+    GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
+        return values<std::tuple<Ts...>>( tuples );
+    }
+
+    // Tag type to signal that a generator sequence should convert arguments to a specific type
+    template <typename T>
+    struct as {};
+
+    template<typename T, typename... Gs>
+    auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
+        return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
+    }
+    template<typename T>
+    auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
+        return Generators<T>(std::move(generator));
+    }
+    template<typename T, typename... Gs>
+    auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
+    }
+    template<typename T, typename U, typename... Gs>
+    auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
+    }
+
+    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+
+    template<typename L>
+    // Note: The type after -> is weird, because VS2015 cannot parse
+    //       the expression used in the typedef inside, when it is in
+    //       return type. Yeah.
+    auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
+        using UnderlyingType = typename decltype(generatorExpression())::type;
+
+        IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
+        if (!tracker.hasGenerator()) {
+            tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
+        }
+
+        auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
+        return generator.get();
+    }
+
+} // namespace Generators
+} // namespace Catch
+
+#define GENERATE( ... ) \
+    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+                                 CATCH_INTERNAL_LINEINFO, \
+                                 [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
+#define GENERATE_COPY( ... ) \
+    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+                                 CATCH_INTERNAL_LINEINFO, \
+                                 [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
+#define GENERATE_REF( ... ) \
+    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+                                 CATCH_INTERNAL_LINEINFO, \
+                                 [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
+
+// end catch_generators.hpp
+// start catch_generators_generic.hpp
+
+namespace Catch {
+namespace Generators {
+
+    template <typename T>
+    class TakeGenerator : public IGenerator<T> {
+        GeneratorWrapper<T> m_generator;
+        size_t m_returned = 0;
+        size_t m_target;
+    public:
+        TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
+            m_generator(std::move(generator)),
+            m_target(target)
+        {
+            assert(target != 0 && "Empty generators are not allowed");
+        }
+        T const& get() const override {
+            return m_generator.get();
+        }
+        bool next() override {
+            ++m_returned;
+            if (m_returned >= m_target) {
+                return false;
+            }
+
+            const auto success = m_generator.next();
+            // If the underlying generator does not contain enough values
+            // then we cut short as well
+            if (!success) {
+                m_returned = m_target;
+            }
+            return success;
+        }
+    };
+
+    template <typename T>
+    GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
+        return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
+    }
+
+    template <typename T, typename Predicate>
+    class FilterGenerator : public IGenerator<T> {
+        GeneratorWrapper<T> m_generator;
+        Predicate m_predicate;
+    public:
+        template <typename P = Predicate>
+        FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
+            m_generator(std::move(generator)),
+            m_predicate(std::forward<P>(pred))
+        {
+            if (!m_predicate(m_generator.get())) {
+                // It might happen that there are no values that pass the
+                // filter. In that case we throw an exception.
+                auto has_initial_value = nextImpl();
+                if (!has_initial_value) {
+                    Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
+                }
+            }
+        }
+
+        T const& get() const override {
+            return m_generator.get();
+        }
+
+        bool next() override {
+            return nextImpl();
+        }
+
+    private:
+        bool nextImpl() {
+            bool success = m_generator.next();
+            if (!success) {
+                return false;
+            }
+            while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
+            return success;
+        }
+    };
+
+    template <typename T, typename Predicate>
+    GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
+        return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
+    }
+
+    template <typename T>
+    class RepeatGenerator : public IGenerator<T> {
+        static_assert(!std::is_same<T, bool>::value,
+            "RepeatGenerator currently does not support bools"
+            "because of std::vector<bool> specialization");
+        GeneratorWrapper<T> m_generator;
+        mutable std::vector<T> m_returned;
+        size_t m_target_repeats;
+        size_t m_current_repeat = 0;
+        size_t m_repeat_index = 0;
+    public:
+        RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
+            m_generator(std::move(generator)),
+            m_target_repeats(repeats)
+        {
+            assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
+        }
+
+        T const& get() const override {
+            if (m_current_repeat == 0) {
+                m_returned.push_back(m_generator.get());
+                return m_returned.back();
+            }
+            return m_returned[m_repeat_index];
+        }
+
+        bool next() override {
+            // There are 2 basic cases:
+            // 1) We are still reading the generator
+            // 2) We are reading our own cache
+
+            // In the first case, we need to poke the underlying generator.
+            // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
+            if (m_current_repeat == 0) {
+                const auto success = m_generator.next();
+                if (!success) {
+                    ++m_current_repeat;
+                }
+                return m_current_repeat < m_target_repeats;
+            }
+
+            // In the second case, we need to move indices forward and check that we haven't run up against the end
+            ++m_repeat_index;
+            if (m_repeat_index == m_returned.size()) {
+                m_repeat_index = 0;
+                ++m_current_repeat;
+            }
+            return m_current_repeat < m_target_repeats;
+        }
+    };
+
+    template <typename T>
+    GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
+        return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
+    }
+
+    template <typename T, typename U, typename Func>
+    class MapGenerator : public IGenerator<T> {
+        // TBD: provide static assert for mapping function, for friendly error message
+        GeneratorWrapper<U> m_generator;
+        Func m_function;
+        // To avoid returning dangling reference, we have to save the values
+        T m_cache;
+    public:
+        template <typename F2 = Func>
+        MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
+            m_generator(std::move(generator)),
+            m_function(std::forward<F2>(function)),
+            m_cache(m_function(m_generator.get()))
+        {}
+
+        T const& get() const override {
+            return m_cache;
+        }
+        bool next() override {
+            const auto success = m_generator.next();
+            if (success) {
+                m_cache = m_function(m_generator.get());
+            }
+            return success;
+        }
+    };
+
+    template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
+    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
+        return GeneratorWrapper<T>(
+            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
+        );
+    }
+
+    template <typename T, typename U, typename Func>
+    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
+        return GeneratorWrapper<T>(
+            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
+        );
+    }
+
+    template <typename T>
+    class ChunkGenerator final : public IGenerator<std::vector<T>> {
+        std::vector<T> m_chunk;
+        size_t m_chunk_size;
+        GeneratorWrapper<T> m_generator;
+        bool m_used_up = false;
+    public:
+        ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
+            m_chunk_size(size), m_generator(std::move(generator))
+        {
+            m_chunk.reserve(m_chunk_size);
+            if (m_chunk_size != 0) {
+                m_chunk.push_back(m_generator.get());
+                for (size_t i = 1; i < m_chunk_size; ++i) {
+                    if (!m_generator.next()) {
+                        Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
+                    }
+                    m_chunk.push_back(m_generator.get());
+                }
+            }
+        }
+        std::vector<T> const& get() const override {
+            return m_chunk;
+        }
+        bool next() override {
+            m_chunk.clear();
+            for (size_t idx = 0; idx < m_chunk_size; ++idx) {
+                if (!m_generator.next()) {
+                    return false;
+                }
+                m_chunk.push_back(m_generator.get());
+            }
+            return true;
+        }
+    };
+
+    template <typename T>
+    GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
+        return GeneratorWrapper<std::vector<T>>(
+            pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
+        );
+    }
+
+} // namespace Generators
+} // namespace Catch
+
+// end catch_generators_generic.hpp
+// start catch_generators_specific.hpp
+
+// start catch_context.h
+
+#include <memory>
+
+namespace Catch {
+
+    struct IResultCapture;
+    struct IRunner;
+    struct IConfig;
+    struct IMutableContext;
+
+    using IConfigPtr = std::shared_ptr<IConfig const>;
+
+    struct IContext
+    {
+        virtual ~IContext();
+
+        virtual IResultCapture* getResultCapture() = 0;
+        virtual IRunner* getRunner() = 0;
+        virtual IConfigPtr const& getConfig() const = 0;
+    };
+
+    struct IMutableContext : IContext
+    {
+        virtual ~IMutableContext();
+        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+        virtual void setRunner( IRunner* runner ) = 0;
+        virtual void setConfig( IConfigPtr const& config ) = 0;
+
+    private:
+        static IMutableContext *currentContext;
+        friend IMutableContext& getCurrentMutableContext();
+        friend void cleanUpContext();
+        static void createContext();
+    };
+
+    inline IMutableContext& getCurrentMutableContext()
+    {
+        if( !IMutableContext::currentContext )
+            IMutableContext::createContext();
+        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
+        return *IMutableContext::currentContext;
+    }
+
+    inline IContext& getCurrentContext()
+    {
+        return getCurrentMutableContext();
+    }
+
+    void cleanUpContext();
+
+    class SimplePcg32;
+    SimplePcg32& rng();
+}
+
+// end catch_context.h
+// start catch_interfaces_config.h
+
+// start catch_option.hpp
+
+namespace Catch {
+
+    // An optional type
+    template<typename T>
+    class Option {
+    public:
+        Option() : nullableValue( nullptr ) {}
+        Option( T const& _value )
+        : nullableValue( new( storage ) T( _value ) )
+        {}
+        Option( Option const& _other )
+        : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
+        {}
+
+        ~Option() {
+            reset();
+        }
+
+        Option& operator= ( Option const& _other ) {
+            if( &_other != this ) {
+                reset();
+                if( _other )
+                    nullableValue = new( storage ) T( *_other );
+            }
+            return *this;
+        }
+        Option& operator = ( T const& _value ) {
+            reset();
+            nullableValue = new( storage ) T( _value );
+            return *this;
+        }
+
+        void reset() {
+            if( nullableValue )
+                nullableValue->~T();
+            nullableValue = nullptr;
+        }
+
+        T& operator*() { return *nullableValue; }
+        T const& operator*() const { return *nullableValue; }
+        T* operator->() { return nullableValue; }
+        const T* operator->() const { return nullableValue; }
+
+        T valueOr( T const& defaultValue ) const {
+            return nullableValue ? *nullableValue : defaultValue;
+        }
+
+        bool some() const { return nullableValue != nullptr; }
+        bool none() const { return nullableValue == nullptr; }
+
+        bool operator !() const { return nullableValue == nullptr; }
+        explicit operator bool() const {
+            return some();
+        }
+
+    private:
+        T *nullableValue;
+        alignas(alignof(T)) char storage[sizeof(T)];
+    };
+
+} // end namespace Catch
+
+// end catch_option.hpp
+#include <chrono>
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+    enum class Verbosity {
+        Quiet = 0,
+        Normal,
+        High
+    };
+
+    struct WarnAbout { enum What {
+        Nothing = 0x00,
+        NoAssertions = 0x01,
+        NoTests = 0x02
+    }; };
+
+    struct ShowDurations { enum OrNot {
+        DefaultForReporter,
+        Always,
+        Never
+    }; };
+    struct RunTests { enum InWhatOrder {
+        InDeclarationOrder,
+        InLexicographicalOrder,
+        InRandomOrder
+    }; };
+    struct UseColour { enum YesOrNo {
+        Auto,
+        Yes,
+        No
+    }; };
+    struct WaitForKeypress { enum When {
+        Never,
+        BeforeStart = 1,
+        BeforeExit = 2,
+        BeforeStartAndExit = BeforeStart | BeforeExit
+    }; };
+
+    class TestSpec;
+
+    struct IConfig : NonCopyable {
+
+        virtual ~IConfig();
+
+        virtual bool allowThrows() const = 0;
+        virtual std::ostream& stream() const = 0;
+        virtual std::string name() const = 0;
+        virtual bool includeSuccessfulResults() const = 0;
+        virtual bool shouldDebugBreak() const = 0;
+        virtual bool warnAboutMissingAssertions() const = 0;
+        virtual bool warnAboutNoTests() const = 0;
+        virtual int abortAfter() const = 0;
+        virtual bool showInvisibles() const = 0;
+        virtual ShowDurations::OrNot showDurations() const = 0;
+        virtual double minDuration() const = 0;
+        virtual TestSpec const& testSpec() const = 0;
+        virtual bool hasTestFilters() const = 0;
+        virtual std::vector<std::string> const& getTestsOrTags() const = 0;
+        virtual RunTests::InWhatOrder runOrder() const = 0;
+        virtual unsigned int rngSeed() const = 0;
+        virtual UseColour::YesOrNo useColour() const = 0;
+        virtual std::vector<std::string> const& getSectionsToRun() const = 0;
+        virtual Verbosity verbosity() const = 0;
+
+        virtual bool benchmarkNoAnalysis() const = 0;
+        virtual int benchmarkSamples() const = 0;
+        virtual double benchmarkConfidenceInterval() const = 0;
+        virtual unsigned int benchmarkResamples() const = 0;
+        virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
+    };
+
+    using IConfigPtr = std::shared_ptr<IConfig const>;
+}
+
+// end catch_interfaces_config.h
+// start catch_random_number_generator.h
+
+#include <cstdint>
+
+namespace Catch {
+
+    // This is a simple implementation of C++11 Uniform Random Number
+    // Generator. It does not provide all operators, because Catch2
+    // does not use it, but it should behave as expected inside stdlib's
+    // distributions.
+    // The implementation is based on the PCG family (http://pcg-random.org)
+    class SimplePcg32 {
+        using state_type = std::uint64_t;
+    public:
+        using result_type = std::uint32_t;
+        static constexpr result_type (min)() {
+            return 0;
+        }
+        static constexpr result_type (max)() {
+            return static_cast<result_type>(-1);
+        }
+
+        // Provide some default initial state for the default constructor
+        SimplePcg32():SimplePcg32(0xed743cc4U) {}
+
+        explicit SimplePcg32(result_type seed_);
+
+        void seed(result_type seed_);
+        void discard(uint64_t skip);
+
+        result_type operator()();
+
+    private:
+        friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+        friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+
+        // In theory we also need operator<< and operator>>
+        // In practice we do not use them, so we will skip them for now
+
+        std::uint64_t m_state;
+        // This part of the state determines which "stream" of the numbers
+        // is chosen -- we take it as a constant for Catch2, so we only
+        // need to deal with seeding the main state.
+        // Picked by reading 8 bytes from `/dev/random` :-)
+        static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
+    };
+
+} // end namespace Catch
+
+// end catch_random_number_generator.h
+#include <random>
+
+namespace Catch {
+namespace Generators {
+
+template <typename Float>
+class RandomFloatingGenerator final : public IGenerator<Float> {
+    Catch::SimplePcg32& m_rng;
+    std::uniform_real_distribution<Float> m_dist;
+    Float m_current_number;
+public:
+
+    RandomFloatingGenerator(Float a, Float b):
+        m_rng(rng()),
+        m_dist(a, b) {
+        static_cast<void>(next());
+    }
+
+    Float const& get() const override {
+        return m_current_number;
+    }
+    bool next() override {
+        m_current_number = m_dist(m_rng);
+        return true;
+    }
+};
+
+template <typename Integer>
+class RandomIntegerGenerator final : public IGenerator<Integer> {
+    Catch::SimplePcg32& m_rng;
+    std::uniform_int_distribution<Integer> m_dist;
+    Integer m_current_number;
+public:
+
+    RandomIntegerGenerator(Integer a, Integer b):
+        m_rng(rng()),
+        m_dist(a, b) {
+        static_cast<void>(next());
+    }
+
+    Integer const& get() const override {
+        return m_current_number;
+    }
+    bool next() override {
+        m_current_number = m_dist(m_rng);
+        return true;
+    }
+};
+
+// TODO: Ideally this would be also constrained against the various char types,
+//       but I don't expect users to run into that in practice.
+template <typename T>
+typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
+GeneratorWrapper<T>>::type
+random(T a, T b) {
+    return GeneratorWrapper<T>(
+        pf::make_unique<RandomIntegerGenerator<T>>(a, b)
+    );
+}
+
+template <typename T>
+typename std::enable_if<std::is_floating_point<T>::value,
+GeneratorWrapper<T>>::type
+random(T a, T b) {
+    return GeneratorWrapper<T>(
+        pf::make_unique<RandomFloatingGenerator<T>>(a, b)
+    );
+}
+
+template <typename T>
+class RangeGenerator final : public IGenerator<T> {
+    T m_current;
+    T m_end;
+    T m_step;
+    bool m_positive;
+
+public:
+    RangeGenerator(T const& start, T const& end, T const& step):
+        m_current(start),
+        m_end(end),
+        m_step(step),
+        m_positive(m_step > T(0))
+    {
+        assert(m_current != m_end && "Range start and end cannot be equal");
+        assert(m_step != T(0) && "Step size cannot be zero");
+        assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
+    }
+
+    RangeGenerator(T const& start, T const& end):
+        RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
+    {}
+
+    T const& get() const override {
+        return m_current;
+    }
+
+    bool next() override {
+        m_current += m_step;
+        return (m_positive) ? (m_current < m_end) : (m_current > m_end);
+    }
+};
+
+template <typename T>
+GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
+    static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
+    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
+}
+
+template <typename T>
+GeneratorWrapper<T> range(T const& start, T const& end) {
+    static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
+    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
+}
+
+template <typename T>
+class IteratorGenerator final : public IGenerator<T> {
+    static_assert(!std::is_same<T, bool>::value,
+        "IteratorGenerator currently does not support bools"
+        "because of std::vector<bool> specialization");
+
+    std::vector<T> m_elems;
+    size_t m_current = 0;
+public:
+    template <typename InputIterator, typename InputSentinel>
+    IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
+        if (m_elems.empty()) {
+            Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
+        }
+    }
+
+    T const& get() const override {
+        return m_elems[m_current];
+    }
+
+    bool next() override {
+        ++m_current;
+        return m_current != m_elems.size();
+    }
+};
+
+template <typename InputIterator,
+          typename InputSentinel,
+          typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
+GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
+    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
+}
+
+template <typename Container,
+          typename ResultType = typename Container::value_type>
+GeneratorWrapper<ResultType> from_range(Container const& cnt) {
+    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
+}
+
+} // namespace Generators
+} // namespace Catch
+
+// end catch_generators_specific.hpp
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// start catch_test_case_info.h
+
+#include <string>
+#include <vector>
+#include <memory>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+    struct ITestInvoker;
+
+    struct TestCaseInfo {
+        enum SpecialProperties{
+            None = 0,
+            IsHidden = 1 << 1,
+            ShouldFail = 1 << 2,
+            MayFail = 1 << 3,
+            Throws = 1 << 4,
+            NonPortable = 1 << 5,
+            Benchmark = 1 << 6
+        };
+
+        TestCaseInfo(   std::string const& _name,
+                        std::string const& _className,
+                        std::string const& _description,
+                        std::vector<std::string> const& _tags,
+                        SourceLineInfo const& _lineInfo );
+
+        friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
+
+        bool isHidden() const;
+        bool throws() const;
+        bool okToFail() const;
+        bool expectedToFail() const;
+
+        std::string tagsAsString() const;
+
+        std::string name;
+        std::string className;
+        std::string description;
+        std::vector<std::string> tags;
+        std::vector<std::string> lcaseTags;
+        SourceLineInfo lineInfo;
+        SpecialProperties properties;
+    };
+
+    class TestCase : public TestCaseInfo {
+    public:
+
+        TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
+
+        TestCase withName( std::string const& _newName ) const;
+
+        void invoke() const;
+
+        TestCaseInfo const& getTestCaseInfo() const;
+
+        bool operator == ( TestCase const& other ) const;
+        bool operator < ( TestCase const& other ) const;
+
+    private:
+        std::shared_ptr<ITestInvoker> test;
+    };
+
+    TestCase makeTestCase(  ITestInvoker* testCase,
+                            std::string const& className,
+                            NameAndTags const& nameAndTags,
+                            SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_test_case_info.h
+// start catch_interfaces_runner.h
+
+namespace Catch {
+
+    struct IRunner {
+        virtual ~IRunner();
+        virtual bool aborting() const = 0;
+    };
+}
+
+// end catch_interfaces_runner.h
+
+#ifdef __OBJC__
+// start catch_objc.hpp
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch {
+
+    class OcMethod : public ITestInvoker {
+
+    public:
+        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+        virtual void invoke() const {
+            id obj = [[m_cls alloc] init];
+
+            performOptionalSelector( obj, @selector(setUp)  );
+            performOptionalSelector( obj, m_sel );
+            performOptionalSelector( obj, @selector(tearDown)  );
+
+            arcSafeRelease( obj );
+        }
+    private:
+        virtual ~OcMethod() {}
+
+        Class m_cls;
+        SEL m_sel;
+    };
+
+    namespace Detail{
+
+        inline std::string getAnnotation(   Class cls,
+                                            std::string const& annotationName,
+                                            std::string const& testCaseName ) {
+            NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+            SEL sel = NSSelectorFromString( selStr );
+            arcSafeRelease( selStr );
+            id value = performOptionalSelector( cls, sel );
+            if( value )
+                return [(NSString*)value UTF8String];
+            return "";
+        }
+    }
+
+    inline std::size_t registerTestMethods() {
+        std::size_t noTestMethods = 0;
+        int noClasses = objc_getClassList( nullptr, 0 );
+
+        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+        objc_getClassList( classes, noClasses );
+
+        for( int c = 0; c < noClasses; c++ ) {
+            Class cls = classes[c];
+            {
+                u_int count;
+                Method* methods = class_copyMethodList( cls, &count );
+                for( u_int m = 0; m < count ; m++ ) {
+                    SEL selector = method_getName(methods[m]);
+                    std::string methodName = sel_getName(selector);
+                    if( startsWith( methodName, "Catch_TestCase_" ) ) {
+                        std::string testCaseName = methodName.substr( 15 );
+                        std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+                        std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+                        const char* className = class_getName( cls );
+
+                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
+                        noTestMethods++;
+                    }
+                }
+                free(methods);
+            }
+        }
+        return noTestMethods;
+    }
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+
+    namespace Matchers {
+        namespace Impl {
+        namespace NSStringMatchers {
+
+            struct StringHolder : MatcherBase<NSString*>{
+                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+                StringHolder() {
+                    arcSafeRelease( m_substr );
+                }
+
+                bool match( NSString* str ) const override {
+                    return false;
+                }
+
+                NSString* CATCH_ARC_STRONG m_substr;
+            };
+
+            struct Equals : StringHolder {
+                Equals( NSString* substr ) : StringHolder( substr ){}
+
+                bool match( NSString* str ) const override {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str isEqualToString:m_substr];
+                }
+
+                std::string describe() const override {
+                    return "equals string: " + Catch::Detail::stringify( m_substr );
+                }
+            };
+
+            struct Contains : StringHolder {
+                Contains( NSString* substr ) : StringHolder( substr ){}
+
+                bool match( NSString* str ) const override {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str rangeOfString:m_substr].location != NSNotFound;
+                }
+
+                std::string describe() const override {
+                    return "contains string: " + Catch::Detail::stringify( m_substr );
+                }
+            };
+
+            struct StartsWith : StringHolder {
+                StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+                bool match( NSString* str ) const override {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str rangeOfString:m_substr].location == 0;
+                }
+
+                std::string describe() const override {
+                    return "starts with: " + Catch::Detail::stringify( m_substr );
+                }
+            };
+            struct EndsWith : StringHolder {
+                EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+                bool match( NSString* str ) const override {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+                }
+
+                std::string describe() const override {
+                    return "ends with: " + Catch::Detail::stringify( m_substr );
+                }
+            };
+
+        } // namespace NSStringMatchers
+        } // namespace Impl
+
+        inline Impl::NSStringMatchers::Equals
+            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+        inline Impl::NSStringMatchers::Contains
+            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+        inline Impl::NSStringMatchers::StartsWith
+            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+        inline Impl::NSStringMatchers::EndsWith
+            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+    } // namespace Matchers
+
+    using namespace Matchers;
+
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
+#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
+{ \
+return @ name; \
+} \
++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
+{ \
+return @ desc; \
+} \
+-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
+
+#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
+
+// end catch_objc.hpp
+#endif
+
+// Benchmarking needs the externally-facing parts of reporters to work
+#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+// start catch_external_interfaces.h
+
+// start catch_reporter_bases.hpp
+
+// start catch_interfaces_reporter.h
+
+// start catch_config.hpp
+
+// start catch_test_spec_parser.h
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// start catch_test_spec.h
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// start catch_wildcard_pattern.h
+
+namespace Catch
+{
+    class WildcardPattern {
+        enum WildcardPosition {
+            NoWildcard = 0,
+            WildcardAtStart = 1,
+            WildcardAtEnd = 2,
+            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+        };
+
+    public:
+
+        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
+        virtual ~WildcardPattern() = default;
+        virtual bool matches( std::string const& str ) const;
+
+    private:
+        std::string normaliseString( std::string const& str ) const;
+        CaseSensitive::Choice m_caseSensitivity;
+        WildcardPosition m_wildcard = NoWildcard;
+        std::string m_pattern;
+    };
+}
+
+// end catch_wildcard_pattern.h
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+    struct IConfig;
+
+    class TestSpec {
+        class Pattern {
+        public:
+            explicit Pattern( std::string const& name );
+            virtual ~Pattern();
+            virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+            std::string const& name() const;
+        private:
+            std::string const m_name;
+        };
+        using PatternPtr = std::shared_ptr<Pattern>;
+
+        class NamePattern : public Pattern {
+        public:
+            explicit NamePattern( std::string const& name, std::string const& filterString );
+            bool matches( TestCaseInfo const& testCase ) const override;
+        private:
+            WildcardPattern m_wildcardPattern;
+        };
+
+        class TagPattern : public Pattern {
+        public:
+            explicit TagPattern( std::string const& tag, std::string const& filterString );
+            bool matches( TestCaseInfo const& testCase ) const override;
+        private:
+            std::string m_tag;
+        };
+
+        class ExcludedPattern : public Pattern {
+        public:
+            explicit ExcludedPattern( PatternPtr const& underlyingPattern );
+            bool matches( TestCaseInfo const& testCase ) const override;
+        private:
+            PatternPtr m_underlyingPattern;
+        };
+
+        struct Filter {
+            std::vector<PatternPtr> m_patterns;
+
+            bool matches( TestCaseInfo const& testCase ) const;
+            std::string name() const;
+        };
+
+    public:
+        struct FilterMatch {
+            std::string name;
+            std::vector<TestCase const*> tests;
+        };
+        using Matches = std::vector<FilterMatch>;
+        using vectorStrings = std::vector<std::string>;
+
+        bool hasFilters() const;
+        bool matches( TestCaseInfo const& testCase ) const;
+        Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
+        const vectorStrings & getInvalidArgs() const;
+
+    private:
+        std::vector<Filter> m_filters;
+        std::vector<std::string> m_invalidArgs;
+        friend class TestSpecParser;
+    };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_test_spec.h
+// start catch_interfaces_tag_alias_registry.h
+
+#include <string>
+
+namespace Catch {
+
+    struct TagAlias;
+
+    struct ITagAliasRegistry {
+        virtual ~ITagAliasRegistry();
+        // Nullptr if not present
+        virtual TagAlias const* find( std::string const& alias ) const = 0;
+        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+        static ITagAliasRegistry const& get();
+    };
+
+} // end namespace Catch
+
+// end catch_interfaces_tag_alias_registry.h
+namespace Catch {
+
+    class TestSpecParser {
+        enum Mode{ None, Name, QuotedName, Tag, EscapedName };
+        Mode m_mode = None;
+        Mode lastMode = None;
+        bool m_exclusion = false;
+        std::size_t m_pos = 0;
+        std::size_t m_realPatternPos = 0;
+        std::string m_arg;
+        std::string m_substring;
+        std::string m_patternName;
+        std::vector<std::size_t> m_escapeChars;
+        TestSpec::Filter m_currentFilter;
+        TestSpec m_testSpec;
+        ITagAliasRegistry const* m_tagAliases = nullptr;
+
+    public:
+        TestSpecParser( ITagAliasRegistry const& tagAliases );
+
+        TestSpecParser& parse( std::string const& arg );
+        TestSpec testSpec();
+
+    private:
+        bool visitChar( char c );
+        void startNewMode( Mode mode );
+        bool processNoneChar( char c );
+        void processNameChar( char c );
+        bool processOtherChar( char c );
+        void endMode();
+        void escape();
+        bool isControlChar( char c ) const;
+        void saveLastMode();
+        void revertBackToLastMode();
+        void addFilter();
+        bool separate();
+
+        // Handles common preprocessing of the pattern for name/tag patterns
+        std::string preprocessPattern();
+        // Adds the current pattern as a test name
+        void addNamePattern();
+        // Adds the current pattern as a tag
+        void addTagPattern();
+
+        inline void addCharToPattern(char c) {
+            m_substring += c;
+            m_patternName += c;
+            m_realPatternPos++;
+        }
+
+    };
+    TestSpec parseTestSpec( std::string const& arg );
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_test_spec_parser.h
+// Libstdc++ doesn't like incomplete classes for unique_ptr
+
+#include <memory>
+#include <vector>
+#include <string>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+    struct IStream;
+
+    struct ConfigData {
+        bool listTests = false;
+        bool listTags = false;
+        bool listReporters = false;
+        bool listTestNamesOnly = false;
+
+        bool showSuccessfulTests = false;
+        bool shouldDebugBreak = false;
+        bool noThrow = false;
+        bool showHelp = false;
+        bool showInvisibles = false;
+        bool filenamesAsTags = false;
+        bool libIdentify = false;
+
+        int abortAfter = -1;
+        unsigned int rngSeed = 0;
+
+        bool benchmarkNoAnalysis = false;
+        unsigned int benchmarkSamples = 100;
+        double benchmarkConfidenceInterval = 0.95;
+        unsigned int benchmarkResamples = 100000;
+        std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
+
+        Verbosity verbosity = Verbosity::Normal;
+        WarnAbout::What warnings = WarnAbout::Nothing;
+        ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
+        double minDuration = -1;
+        RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
+        UseColour::YesOrNo useColour = UseColour::Auto;
+        WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
+
+        std::string outputFilename;
+        std::string name;
+        std::string processName;
+#ifndef CATCH_CONFIG_DEFAULT_REPORTER
+#define CATCH_CONFIG_DEFAULT_REPORTER "console"
+#endif
+        std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
+#undef CATCH_CONFIG_DEFAULT_REPORTER
+
+        std::vector<std::string> testsOrTags;
+        std::vector<std::string> sectionsToRun;
+    };
+
+    class Config : public IConfig {
+    public:
+
+        Config() = default;
+        Config( ConfigData const& data );
+        virtual ~Config() = default;
+
+        std::string const& getFilename() const;
+
+        bool listTests() const;
+        bool listTestNamesOnly() const;
+        bool listTags() const;
+        bool listReporters() const;
+
+        std::string getProcessName() const;
+        std::string const& getReporterName() const;
+
+        std::vector<std::string> const& getTestsOrTags() const override;
+        std::vector<std::string> const& getSectionsToRun() const override;
+
+        TestSpec const& testSpec() const override;
+        bool hasTestFilters() const override;
+
+        bool showHelp() const;
+
+        // IConfig interface
+        bool allowThrows() const override;
+        std::ostream& stream() const override;
+        std::string name() const override;
+        bool includeSuccessfulResults() const override;
+        bool warnAboutMissingAssertions() const override;
+        bool warnAboutNoTests() const override;
+        ShowDurations::OrNot showDurations() const override;
+        double minDuration() const override;
+        RunTests::InWhatOrder runOrder() const override;
+        unsigned int rngSeed() const override;
+        UseColour::YesOrNo useColour() const override;
+        bool shouldDebugBreak() const override;
+        int abortAfter() const override;
+        bool showInvisibles() const override;
+        Verbosity verbosity() const override;
+        bool benchmarkNoAnalysis() const override;
+        int benchmarkSamples() const override;
+        double benchmarkConfidenceInterval() const override;
+        unsigned int benchmarkResamples() const override;
+        std::chrono::milliseconds benchmarkWarmupTime() const override;
+
+    private:
+
+        IStream const* openStream();
+        ConfigData m_data;
+
+        std::unique_ptr<IStream const> m_stream;
+        TestSpec m_testSpec;
+        bool m_hasTestFilters = false;
+    };
+
+} // end namespace Catch
+
+// end catch_config.hpp
+// start catch_assertionresult.h
+
+#include <string>
+
+namespace Catch {
+
+    struct AssertionResultData
+    {
+        AssertionResultData() = delete;
+
+        AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
+
+        std::string message;
+        mutable std::string reconstructedExpression;
+        LazyExpression lazyExpression;
+        ResultWas::OfType resultType;
+
+        std::string reconstructExpression() const;
+    };
+
+    class AssertionResult {
+    public:
+        AssertionResult() = delete;
+        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+
+        bool isOk() const;
+        bool succeeded() const;
+        ResultWas::OfType getResultType() const;
+        bool hasExpression() const;
+        bool hasMessage() const;
+        std::string getExpression() const;
+        std::string getExpressionInMacro() const;
+        bool hasExpandedExpression() const;
+        std::string getExpandedExpression() const;
+        std::string getMessage() const;
+        SourceLineInfo getSourceInfo() const;
+        StringRef getTestMacroName() const;
+
+    //protected:
+        AssertionInfo m_info;
+        AssertionResultData m_resultData;
+    };
+
+} // end namespace Catch
+
+// end catch_assertionresult.h
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+// start catch_estimate.hpp
+
+ // Statistics estimates
+
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct Estimate {
+            Duration point;
+            Duration lower_bound;
+            Duration upper_bound;
+            double confidence_interval;
+
+            template <typename Duration2>
+            operator Estimate<Duration2>() const {
+                return { point, lower_bound, upper_bound, confidence_interval };
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_estimate.hpp
+// start catch_outlier_classification.hpp
+
+// Outlier information
+
+namespace Catch {
+    namespace Benchmark {
+        struct OutlierClassification {
+            int samples_seen = 0;
+            int low_severe = 0;     // more than 3 times IQR below Q1
+            int low_mild = 0;       // 1.5 to 3 times IQR below Q1
+            int high_mild = 0;      // 1.5 to 3 times IQR above Q3
+            int high_severe = 0;    // more than 3 times IQR above Q3
+
+            int total() const {
+                return low_severe + low_mild + high_mild + high_severe;
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_outlier_classification.hpp
+
+#include <iterator>
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+#include <string>
+#include <iosfwd>
+#include <map>
+#include <set>
+#include <memory>
+#include <algorithm>
+
+namespace Catch {
+
+    struct ReporterConfig {
+        explicit ReporterConfig( IConfigPtr const& _fullConfig );
+
+        ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
+
+        std::ostream& stream() const;
+        IConfigPtr fullConfig() const;
+
+    private:
+        std::ostream* m_stream;
+        IConfigPtr m_fullConfig;
+    };
+
+    struct ReporterPreferences {
+        bool shouldRedirectStdOut = false;
+        bool shouldReportAllAssertions = false;
+    };
+
+    template<typename T>
+    struct LazyStat : Option<T> {
+        LazyStat& operator=( T const& _value ) {
+            Option<T>::operator=( _value );
+            used = false;
+            return *this;
+        }
+        void reset() {
+            Option<T>::reset();
+            used = false;
+        }
+        bool used = false;
+    };
+
+    struct TestRunInfo {
+        TestRunInfo( std::string const& _name );
+        std::string name;
+    };
+    struct GroupInfo {
+        GroupInfo(  std::string const& _name,
+                    std::size_t _groupIndex,
+                    std::size_t _groupsCount );
+
+        std::string name;
+        std::size_t groupIndex;
+        std::size_t groupsCounts;
+    };
+
+    struct AssertionStats {
+        AssertionStats( AssertionResult const& _assertionResult,
+                        std::vector<MessageInfo> const& _infoMessages,
+                        Totals const& _totals );
+
+        AssertionStats( AssertionStats const& )              = default;
+        AssertionStats( AssertionStats && )                  = default;
+        AssertionStats& operator = ( AssertionStats const& ) = delete;
+        AssertionStats& operator = ( AssertionStats && )     = delete;
+        virtual ~AssertionStats();
+
+        AssertionResult assertionResult;
+        std::vector<MessageInfo> infoMessages;
+        Totals totals;
+    };
+
+    struct SectionStats {
+        SectionStats(   SectionInfo const& _sectionInfo,
+                        Counts const& _assertions,
+                        double _durationInSeconds,
+                        bool _missingAssertions );
+        SectionStats( SectionStats const& )              = default;
+        SectionStats( SectionStats && )                  = default;
+        SectionStats& operator = ( SectionStats const& ) = default;
+        SectionStats& operator = ( SectionStats && )     = default;
+        virtual ~SectionStats();
+
+        SectionInfo sectionInfo;
+        Counts assertions;
+        double durationInSeconds;
+        bool missingAssertions;
+    };
+
+    struct TestCaseStats {
+        TestCaseStats(  TestCaseInfo const& _testInfo,
+                        Totals const& _totals,
+                        std::string const& _stdOut,
+                        std::string const& _stdErr,
+                        bool _aborting );
+
+        TestCaseStats( TestCaseStats const& )              = default;
+        TestCaseStats( TestCaseStats && )                  = default;
+        TestCaseStats& operator = ( TestCaseStats const& ) = default;
+        TestCaseStats& operator = ( TestCaseStats && )     = default;
+        virtual ~TestCaseStats();
+
+        TestCaseInfo testInfo;
+        Totals totals;
+        std::string stdOut;
+        std::string stdErr;
+        bool aborting;
+    };
+
+    struct TestGroupStats {
+        TestGroupStats( GroupInfo const& _groupInfo,
+                        Totals const& _totals,
+                        bool _aborting );
+        TestGroupStats( GroupInfo const& _groupInfo );
+
+        TestGroupStats( TestGroupStats const& )              = default;
+        TestGroupStats( TestGroupStats && )                  = default;
+        TestGroupStats& operator = ( TestGroupStats const& ) = default;
+        TestGroupStats& operator = ( TestGroupStats && )     = default;
+        virtual ~TestGroupStats();
+
+        GroupInfo groupInfo;
+        Totals totals;
+        bool aborting;
+    };
+
+    struct TestRunStats {
+        TestRunStats(   TestRunInfo const& _runInfo,
+                        Totals const& _totals,
+                        bool _aborting );
+
+        TestRunStats( TestRunStats const& )              = default;
+        TestRunStats( TestRunStats && )                  = default;
+        TestRunStats& operator = ( TestRunStats const& ) = default;
+        TestRunStats& operator = ( TestRunStats && )     = default;
+        virtual ~TestRunStats();
+
+        TestRunInfo runInfo;
+        Totals totals;
+        bool aborting;
+    };
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    struct BenchmarkInfo {
+        std::string name;
+        double estimatedDuration;
+        int iterations;
+        int samples;
+        unsigned int resamples;
+        double clockResolution;
+        double clockCost;
+    };
+
+    template <class Duration>
+    struct BenchmarkStats {
+        BenchmarkInfo info;
+
+        std::vector<Duration> samples;
+        Benchmark::Estimate<Duration> mean;
+        Benchmark::Estimate<Duration> standardDeviation;
+        Benchmark::OutlierClassification outliers;
+        double outlierVariance;
+
+        template <typename Duration2>
+        operator BenchmarkStats<Duration2>() const {
+            std::vector<Duration2> samples2;
+            samples2.reserve(samples.size());
+            std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
+            return {
+                info,
+                std::move(samples2),
+                mean,
+                standardDeviation,
+                outliers,
+                outlierVariance,
+            };
+        }
+    };
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+    struct IStreamingReporter {
+        virtual ~IStreamingReporter() = default;
+
+        // Implementing class must also provide the following static methods:
+        // static std::string getDescription();
+        // static std::set<Verbosity> getSupportedVerbosities()
+
+        virtual ReporterPreferences getPreferences() const = 0;
+
+        virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+        virtual void reportInvalidArguments(std::string const&) {}
+
+        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        virtual void benchmarkPreparing( std::string const& ) {}
+        virtual void benchmarkStarting( BenchmarkInfo const& ) {}
+        virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
+        virtual void benchmarkFailed( std::string const& ) {}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+        // The return value indicates if the messages buffer should be cleared:
+        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+
+        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+
+        // Default empty implementation provided
+        virtual void fatalErrorEncountered( StringRef name );
+
+        virtual bool isMulti() const;
+    };
+    using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
+
+    struct IReporterFactory {
+        virtual ~IReporterFactory();
+        virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
+        virtual std::string getDescription() const = 0;
+    };
+    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
+
+    struct IReporterRegistry {
+        using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
+        using Listeners = std::vector<IReporterFactoryPtr>;
+
+        virtual ~IReporterRegistry();
+        virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
+        virtual FactoryMap const& getFactories() const = 0;
+        virtual Listeners const& getListeners() const = 0;
+    };
+
+} // end namespace Catch
+
+// end catch_interfaces_reporter.h
+#include <algorithm>
+#include <cstring>
+#include <cfloat>
+#include <cstdio>
+#include <cassert>
+#include <memory>
+#include <ostream>
+
+namespace Catch {
+    void prepareExpandedExpression(AssertionResult& result);
+
+    // Returns double formatted as %.3f (format expected on output)
+    std::string getFormattedDuration( double duration );
+
+    //! Should the reporter show
+    bool shouldShowDuration( IConfig const& config, double duration );
+
+    std::string serializeFilters( std::vector<std::string> const& container );
+
+    template<typename DerivedT>
+    struct StreamingReporterBase : IStreamingReporter {
+
+        StreamingReporterBase( ReporterConfig const& _config )
+        :   m_config( _config.fullConfig() ),
+            stream( _config.stream() )
+        {
+            m_reporterPrefs.shouldRedirectStdOut = false;
+            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
+        }
+
+        ReporterPreferences getPreferences() const override {
+            return m_reporterPrefs;
+        }
+
+        static std::set<Verbosity> getSupportedVerbosities() {
+            return { Verbosity::Normal };
+        }
+
+        ~StreamingReporterBase() override = default;
+
+        void noMatchingTestCases(std::string const&) override {}
+
+        void reportInvalidArguments(std::string const&) override {}
+
+        void testRunStarting(TestRunInfo const& _testRunInfo) override {
+            currentTestRunInfo = _testRunInfo;
+        }
+
+        void testGroupStarting(GroupInfo const& _groupInfo) override {
+            currentGroupInfo = _groupInfo;
+        }
+
+        void testCaseStarting(TestCaseInfo const& _testInfo) override  {
+            currentTestCaseInfo = _testInfo;
+        }
+        void sectionStarting(SectionInfo const& _sectionInfo) override {
+            m_sectionStack.push_back(_sectionInfo);
+        }
+
+        void sectionEnded(SectionStats const& /* _sectionStats */) override {
+            m_sectionStack.pop_back();
+        }
+        void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
+            currentTestCaseInfo.reset();
+        }
+        void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
+            currentGroupInfo.reset();
+        }
+        void testRunEnded(TestRunStats const& /* _testRunStats */) override {
+            currentTestCaseInfo.reset();
+            currentGroupInfo.reset();
+            currentTestRunInfo.reset();
+        }
+
+        void skipTest(TestCaseInfo const&) override {
+            // Don't do anything with this by default.
+            // It can optionally be overridden in the derived class.
+        }
+
+        IConfigPtr m_config;
+        std::ostream& stream;
+
+        LazyStat<TestRunInfo> currentTestRunInfo;
+        LazyStat<GroupInfo> currentGroupInfo;
+        LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+        std::vector<SectionInfo> m_sectionStack;
+        ReporterPreferences m_reporterPrefs;
+    };
+
+    template<typename DerivedT>
+    struct CumulativeReporterBase : IStreamingReporter {
+        template<typename T, typename ChildNodeT>
+        struct Node {
+            explicit Node( T const& _value ) : value( _value ) {}
+            virtual ~Node() {}
+
+            using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
+            T value;
+            ChildNodes children;
+        };
+        struct SectionNode {
+            explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
+            virtual ~SectionNode() = default;
+
+            bool operator == (SectionNode const& other) const {
+                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+            }
+            bool operator == (std::shared_ptr<SectionNode> const& other) const {
+                return operator==(*other);
+            }
+
+            SectionStats stats;
+            using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
+            using Assertions = std::vector<AssertionStats>;
+            ChildSections childSections;
+            Assertions assertions;
+            std::string stdOut;
+            std::string stdErr;
+        };
+
+        struct BySectionInfo {
+            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+            BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+            bool operator() (std::shared_ptr<SectionNode> const& node) const {
+                return ((node->stats.sectionInfo.name == m_other.name) &&
+                        (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
+            }
+            void operator=(BySectionInfo const&) = delete;
+
+        private:
+            SectionInfo const& m_other;
+        };
+
+        using TestCaseNode = Node<TestCaseStats, SectionNode>;
+        using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
+        using TestRunNode = Node<TestRunStats, TestGroupNode>;
+
+        CumulativeReporterBase( ReporterConfig const& _config )
+        :   m_config( _config.fullConfig() ),
+            stream( _config.stream() )
+        {
+            m_reporterPrefs.shouldRedirectStdOut = false;
+            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
+        }
+        ~CumulativeReporterBase() override = default;
+
+        ReporterPreferences getPreferences() const override {
+            return m_reporterPrefs;
+        }
+
+        static std::set<Verbosity> getSupportedVerbosities() {
+            return { Verbosity::Normal };
+        }
+
+        void testRunStarting( TestRunInfo const& ) override {}
+        void testGroupStarting( GroupInfo const& ) override {}
+
+        void testCaseStarting( TestCaseInfo const& ) override {}
+
+        void sectionStarting( SectionInfo const& sectionInfo ) override {
+            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+            std::shared_ptr<SectionNode> node;
+            if( m_sectionStack.empty() ) {
+                if( !m_rootSection )
+                    m_rootSection = std::make_shared<SectionNode>( incompleteStats );
+                node = m_rootSection;
+            }
+            else {
+                SectionNode& parentNode = *m_sectionStack.back();
+                auto it =
+                    std::find_if(   parentNode.childSections.begin(),
+                                    parentNode.childSections.end(),
+                                    BySectionInfo( sectionInfo ) );
+                if( it == parentNode.childSections.end() ) {
+                    node = std::make_shared<SectionNode>( incompleteStats );
+                    parentNode.childSections.push_back( node );
+                }
+                else
+                    node = *it;
+            }
+            m_sectionStack.push_back( node );
+            m_deepestSection = std::move(node);
+        }
+
+        void assertionStarting(AssertionInfo const&) override {}
+
+        bool assertionEnded(AssertionStats const& assertionStats) override {
+            assert(!m_sectionStack.empty());
+            // AssertionResult holds a pointer to a temporary DecomposedExpression,
+            // which getExpandedExpression() calls to build the expression string.
+            // Our section stack copy of the assertionResult will likely outlive the
+            // temporary, so it must be expanded or discarded now to avoid calling
+            // a destroyed object later.
+            prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
+            SectionNode& sectionNode = *m_sectionStack.back();
+            sectionNode.assertions.push_back(assertionStats);
+            return true;
+        }
+        void sectionEnded(SectionStats const& sectionStats) override {
+            assert(!m_sectionStack.empty());
+            SectionNode& node = *m_sectionStack.back();
+            node.stats = sectionStats;
+            m_sectionStack.pop_back();
+        }
+        void testCaseEnded(TestCaseStats const& testCaseStats) override {
+            auto node = std::make_shared<TestCaseNode>(testCaseStats);
+            assert(m_sectionStack.size() == 0);
+            node->children.push_back(m_rootSection);
+            m_testCases.push_back(node);
+            m_rootSection.reset();
+
+            assert(m_deepestSection);
+            m_deepestSection->stdOut = testCaseStats.stdOut;
+            m_deepestSection->stdErr = testCaseStats.stdErr;
+        }
+        void testGroupEnded(TestGroupStats const& testGroupStats) override {
+            auto node = std::make_shared<TestGroupNode>(testGroupStats);
+            node->children.swap(m_testCases);
+            m_testGroups.push_back(node);
+        }
+        void testRunEnded(TestRunStats const& testRunStats) override {
+            auto node = std::make_shared<TestRunNode>(testRunStats);
+            node->children.swap(m_testGroups);
+            m_testRuns.push_back(node);
+            testRunEndedCumulative();
+        }
+        virtual void testRunEndedCumulative() = 0;
+
+        void skipTest(TestCaseInfo const&) override {}
+
+        IConfigPtr m_config;
+        std::ostream& stream;
+        std::vector<AssertionStats> m_assertions;
+        std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
+        std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
+        std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
+
+        std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
+
+        std::shared_ptr<SectionNode> m_rootSection;
+        std::shared_ptr<SectionNode> m_deepestSection;
+        std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
+        ReporterPreferences m_reporterPrefs;
+    };
+
+    template<char C>
+    char const* getLineOfChars() {
+        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+        if( !*line ) {
+            std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+        }
+        return line;
+    }
+
+    struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
+        TestEventListenerBase( ReporterConfig const& _config );
+
+        static std::set<Verbosity> getSupportedVerbosities();
+
+        void assertionStarting(AssertionInfo const&) override;
+        bool assertionEnded(AssertionStats const&) override;
+    };
+
+} // end namespace Catch
+
+// end catch_reporter_bases.hpp
+// start catch_console_colour.h
+
+namespace Catch {
+
+    struct Colour {
+        enum Code {
+            None = 0,
+
+            White,
+            Red,
+            Green,
+            Blue,
+            Cyan,
+            Yellow,
+            Grey,
+
+            Bright = 0x10,
+
+            BrightRed = Bright | Red,
+            BrightGreen = Bright | Green,
+            LightGrey = Bright | Grey,
+            BrightWhite = Bright | White,
+            BrightYellow = Bright | Yellow,
+
+            // By intention
+            FileName = LightGrey,
+            Warning = BrightYellow,
+            ResultError = BrightRed,
+            ResultSuccess = BrightGreen,
+            ResultExpectedFailure = Warning,
+
+            Error = BrightRed,
+            Success = Green,
+
+            OriginalExpression = Cyan,
+            ReconstructedExpression = BrightYellow,
+
+            SecondaryText = LightGrey,
+            Headers = White
+        };
+
+        // Use constructed object for RAII guard
+        Colour( Code _colourCode );
+        Colour( Colour&& other ) noexcept;
+        Colour& operator=( Colour&& other ) noexcept;
+        ~Colour();
+
+        // Use static method for one-shot changes
+        static void use( Code _colourCode );
+
+    private:
+        bool m_moved = false;
+    };
+
+    std::ostream& operator << ( std::ostream& os, Colour const& );
+
+} // end namespace Catch
+
+// end catch_console_colour.h
+// start catch_reporter_registrars.hpp
+
+
+namespace Catch {
+
+    template<typename T>
+    class ReporterRegistrar {
+
+        class ReporterFactory : public IReporterFactory {
+
+            IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+                return std::unique_ptr<T>( new T( config ) );
+            }
+
+            std::string getDescription() const override {
+                return T::getDescription();
+            }
+        };
+
+    public:
+
+        explicit ReporterRegistrar( std::string const& name ) {
+            getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
+        }
+    };
+
+    template<typename T>
+    class ListenerRegistrar {
+
+        class ListenerFactory : public IReporterFactory {
+
+            IStreamingReporterPtr create( ReporterConfig const& config ) const override {
+                return std::unique_ptr<T>( new T( config ) );
+            }
+            std::string getDescription() const override {
+                return std::string();
+            }
+        };
+
+    public:
+
+        ListenerRegistrar() {
+            getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
+        }
+    };
+}
+
+#if !defined(CATCH_CONFIG_DISABLE)
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \
+    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
+    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+#define CATCH_REGISTER_LISTENER( listenerType ) \
+    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \
+    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \
+    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
+    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+#else // CATCH_CONFIG_DISABLE
+
+#define CATCH_REGISTER_REPORTER(name, reporterType)
+#define CATCH_REGISTER_LISTENER(listenerType)
+
+#endif // CATCH_CONFIG_DISABLE
+
+// end catch_reporter_registrars.hpp
+// Allow users to base their work off existing reporters
+// start catch_reporter_compact.h
+
+namespace Catch {
+
+    struct CompactReporter : StreamingReporterBase<CompactReporter> {
+
+        using StreamingReporterBase::StreamingReporterBase;
+
+        ~CompactReporter() override;
+
+        static std::string getDescription();
+
+        void noMatchingTestCases(std::string const& spec) override;
+
+        void assertionStarting(AssertionInfo const&) override;
+
+        bool assertionEnded(AssertionStats const& _assertionStats) override;
+
+        void sectionEnded(SectionStats const& _sectionStats) override;
+
+        void testRunEnded(TestRunStats const& _testRunStats) override;
+
+    };
+
+} // end namespace Catch
+
+// end catch_reporter_compact.h
+// start catch_reporter_console.h
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
+                              // Note that 4062 (not all labels are handled
+                              // and default is missing) is enabled
+#endif
+
+namespace Catch {
+    // Fwd decls
+    struct SummaryColumn;
+    class TablePrinter;
+
+    struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
+        std::unique_ptr<TablePrinter> m_tablePrinter;
+
+        ConsoleReporter(ReporterConfig const& config);
+        ~ConsoleReporter() override;
+        static std::string getDescription();
+
+        void noMatchingTestCases(std::string const& spec) override;
+
+        void reportInvalidArguments(std::string const&arg) override;
+
+        void assertionStarting(AssertionInfo const&) override;
+
+        bool assertionEnded(AssertionStats const& _assertionStats) override;
+
+        void sectionStarting(SectionInfo const& _sectionInfo) override;
+        void sectionEnded(SectionStats const& _sectionStats) override;
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
+        void benchmarkStarting(BenchmarkInfo const& info) override;
+        void benchmarkEnded(BenchmarkStats<> const& stats) override;
+        void benchmarkFailed(std::string const& error) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+        void testCaseEnded(TestCaseStats const& _testCaseStats) override;
+        void testGroupEnded(TestGroupStats const& _testGroupStats) override;
+        void testRunEnded(TestRunStats const& _testRunStats) override;
+        void testRunStarting(TestRunInfo const& _testRunInfo) override;
+    private:
+
+        void lazyPrint();
+
+        void lazyPrintWithoutClosingBenchmarkTable();
+        void lazyPrintRunInfo();
+        void lazyPrintGroupInfo();
+        void printTestCaseAndSectionHeader();
+
+        void printClosedHeader(std::string const& _name);
+        void printOpenHeader(std::string const& _name);
+
+        // if string has a : in first line will set indent to follow it on
+        // subsequent lines
+        void printHeaderString(std::string const& _string, std::size_t indent = 0);
+
+        void printTotals(Totals const& totals);
+        void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
+
+        void printTotalsDivider(Totals const& totals);
+        void printSummaryDivider();
+        void printTestFilters();
+
+    private:
+        bool m_headerPrinted = false;
+    };
+
+} // end namespace Catch
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+// end catch_reporter_console.h
+// start catch_reporter_junit.h
+
+// start catch_xmlwriter.h
+
+#include <vector>
+
+namespace Catch {
+    enum class XmlFormatting {
+        None = 0x00,
+        Indent = 0x01,
+        Newline = 0x02,
+    };
+
+    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
+    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
+
+    class XmlEncode {
+    public:
+        enum ForWhat { ForTextNodes, ForAttributes };
+
+        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
+
+        void encodeTo( std::ostream& os ) const;
+
+        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
+
+    private:
+        std::string m_str;
+        ForWhat m_forWhat;
+    };
+
+    class XmlWriter {
+    public:
+
+        class ScopedElement {
+        public:
+            ScopedElement( XmlWriter* writer, XmlFormatting fmt );
+
+            ScopedElement( ScopedElement&& other ) noexcept;
+            ScopedElement& operator=( ScopedElement&& other ) noexcept;
+
+            ~ScopedElement();
+
+            ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
+
+            template<typename T>
+            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+                m_writer->writeAttribute( name, attribute );
+                return *this;
+            }
+
+        private:
+            mutable XmlWriter* m_writer = nullptr;
+            XmlFormatting m_fmt;
+        };
+
+        XmlWriter( std::ostream& os = Catch::cout() );
+        ~XmlWriter();
+
+        XmlWriter( XmlWriter const& ) = delete;
+        XmlWriter& operator=( XmlWriter const& ) = delete;
+
+        XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
+
+        ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
+
+        XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
+
+        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
+
+        XmlWriter& writeAttribute( std::string const& name, bool attribute );
+
+        template<typename T>
+        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+            ReusableStringStream rss;
+            rss << attribute;
+            return writeAttribute( name, rss.str() );
+        }
+
+        XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
+
+        XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
+
+        void writeStylesheetRef( std::string const& url );
+
+        XmlWriter& writeBlankLine();
+
+        void ensureTagClosed();
+
+    private:
+
+        void applyFormatting(XmlFormatting fmt);
+
+        void writeDeclaration();
+
+        void newlineIfNecessary();
+
+        bool m_tagIsOpen = false;
+        bool m_needsNewline = false;
+        std::vector<std::string> m_tags;
+        std::string m_indent;
+        std::ostream& m_os;
+    };
+
+}
+
+// end catch_xmlwriter.h
+namespace Catch {
+
+    class JunitReporter : public CumulativeReporterBase<JunitReporter> {
+    public:
+        JunitReporter(ReporterConfig const& _config);
+
+        ~JunitReporter() override;
+
+        static std::string getDescription();
+
+        void noMatchingTestCases(std::string const& /*spec*/) override;
+
+        void testRunStarting(TestRunInfo const& runInfo) override;
+
+        void testGroupStarting(GroupInfo const& groupInfo) override;
+
+        void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
+        bool assertionEnded(AssertionStats const& assertionStats) override;
+
+        void testCaseEnded(TestCaseStats const& testCaseStats) override;
+
+        void testGroupEnded(TestGroupStats const& testGroupStats) override;
+
+        void testRunEndedCumulative() override;
+
+        void writeGroup(TestGroupNode const& groupNode, double suiteTime);
+
+        void writeTestCase(TestCaseNode const& testCaseNode);
+
+        void writeSection( std::string const& className,
+                           std::string const& rootName,
+                           SectionNode const& sectionNode,
+                           bool testOkToFail );
+
+        void writeAssertions(SectionNode const& sectionNode);
+        void writeAssertion(AssertionStats const& stats);
+
+        XmlWriter xml;
+        Timer suiteTimer;
+        std::string stdOutForSuite;
+        std::string stdErrForSuite;
+        unsigned int unexpectedExceptions = 0;
+        bool m_okToFail = false;
+    };
+
+} // end namespace Catch
+
+// end catch_reporter_junit.h
+// start catch_reporter_xml.h
+
+namespace Catch {
+    class XmlReporter : public StreamingReporterBase<XmlReporter> {
+    public:
+        XmlReporter(ReporterConfig const& _config);
+
+        ~XmlReporter() override;
+
+        static std::string getDescription();
+
+        virtual std::string getStylesheetRef() const;
+
+        void writeSourceInfo(SourceLineInfo const& sourceInfo);
+
+    public: // StreamingReporterBase
+
+        void noMatchingTestCases(std::string const& s) override;
+
+        void testRunStarting(TestRunInfo const& testInfo) override;
+
+        void testGroupStarting(GroupInfo const& groupInfo) override;
+
+        void testCaseStarting(TestCaseInfo const& testInfo) override;
+
+        void sectionStarting(SectionInfo const& sectionInfo) override;
+
+        void assertionStarting(AssertionInfo const&) override;
+
+        bool assertionEnded(AssertionStats const& assertionStats) override;
+
+        void sectionEnded(SectionStats const& sectionStats) override;
+
+        void testCaseEnded(TestCaseStats const& testCaseStats) override;
+
+        void testGroupEnded(TestGroupStats const& testGroupStats) override;
+
+        void testRunEnded(TestRunStats const& testRunStats) override;
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
+        void benchmarkStarting(BenchmarkInfo const&) override;
+        void benchmarkEnded(BenchmarkStats<> const&) override;
+        void benchmarkFailed(std::string const&) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+    private:
+        Timer m_testCaseTimer;
+        XmlWriter m_xml;
+        int m_sectionDepth = 0;
+    };
+
+} // end namespace Catch
+
+// end catch_reporter_xml.h
+
+// end catch_external_interfaces.h
+#endif
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+// start catch_benchmarking_all.hpp
+
+// A proxy header that includes all of the benchmarking headers to allow
+// concise include of the benchmarking features. You should prefer the
+// individual includes in standard use.
+
+// start catch_benchmark.hpp
+
+ // Benchmark
+
+// start catch_chronometer.hpp
+
+// User-facing chronometer
+
+
+// start catch_clock.hpp
+
+// Clocks
+
+
+#include <chrono>
+#include <ratio>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Clock>
+        using ClockDuration = typename Clock::duration;
+        template <typename Clock>
+        using FloatDuration = std::chrono::duration<double, typename Clock::period>;
+
+        template <typename Clock>
+        using TimePoint = typename Clock::time_point;
+
+        using default_clock = std::chrono::steady_clock;
+
+        template <typename Clock>
+        struct now {
+            TimePoint<Clock> operator()() const {
+                return Clock::now();
+            }
+        };
+
+        using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_clock.hpp
+// start catch_optimizer.hpp
+
+ // Hinting the optimizer
+
+
+#if defined(_MSC_VER)
+#   include <atomic> // atomic_thread_fence
+#endif
+
+namespace Catch {
+    namespace Benchmark {
+#if defined(__GNUC__) || defined(__clang__)
+        template <typename T>
+        inline void keep_memory(T* p) {
+            asm volatile("" : : "g"(p) : "memory");
+        }
+        inline void keep_memory() {
+            asm volatile("" : : : "memory");
+        }
+
+        namespace Detail {
+            inline void optimizer_barrier() { keep_memory(); }
+        } // namespace Detail
+#elif defined(_MSC_VER)
+
+#pragma optimize("", off)
+        template <typename T>
+        inline void keep_memory(T* p) {
+            // thanks @milleniumbug
+            *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
+        }
+        // TODO equivalent keep_memory()
+#pragma optimize("", on)
+
+        namespace Detail {
+            inline void optimizer_barrier() {
+                std::atomic_thread_fence(std::memory_order_seq_cst);
+            }
+        } // namespace Detail
+
+#endif
+
+        template <typename T>
+        inline void deoptimize_value(T&& x) {
+            keep_memory(&x);
+        }
+
+        template <typename Fn, typename... Args>
+        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
+            deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
+        }
+
+        template <typename Fn, typename... Args>
+        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
+            std::forward<Fn>(fn) (std::forward<Args...>(args...));
+        }
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_optimizer.hpp
+// start catch_complete_invoke.hpp
+
+// Invoke with a special case for void
+
+
+#include <type_traits>
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename T>
+            struct CompleteType { using type = T; };
+            template <>
+            struct CompleteType<void> { struct type {}; };
+
+            template <typename T>
+            using CompleteType_t = typename CompleteType<T>::type;
+
+            template <typename Result>
+            struct CompleteInvoker {
+                template <typename Fun, typename... Args>
+                static Result invoke(Fun&& fun, Args&&... args) {
+                    return std::forward<Fun>(fun)(std::forward<Args>(args)...);
+                }
+            };
+            template <>
+            struct CompleteInvoker<void> {
+                template <typename Fun, typename... Args>
+                static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
+                    std::forward<Fun>(fun)(std::forward<Args>(args)...);
+                    return {};
+                }
+            };
+
+            // invoke and not return void :(
+            template <typename Fun, typename... Args>
+            CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
+                return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
+            }
+
+            const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
+        } // namespace Detail
+
+        template <typename Fun>
+        Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
+            CATCH_TRY{
+                return Detail::complete_invoke(std::forward<Fun>(fun));
+            } CATCH_CATCH_ALL{
+                getResultCapture().benchmarkFailed(translateActiveException());
+                CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
+            }
+        }
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_complete_invoke.hpp
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            struct ChronometerConcept {
+                virtual void start() = 0;
+                virtual void finish() = 0;
+                virtual ~ChronometerConcept() = default;
+            };
+            template <typename Clock>
+            struct ChronometerModel final : public ChronometerConcept {
+                void start() override { started = Clock::now(); }
+                void finish() override { finished = Clock::now(); }
+
+                ClockDuration<Clock> elapsed() const { return finished - started; }
+
+                TimePoint<Clock> started;
+                TimePoint<Clock> finished;
+            };
+        } // namespace Detail
+
+        struct Chronometer {
+        public:
+            template <typename Fun>
+            void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
+
+            int runs() const { return k; }
+
+            Chronometer(Detail::ChronometerConcept& meter, int k)
+                : impl(&meter)
+                , k(k) {}
+
+        private:
+            template <typename Fun>
+            void measure(Fun&& fun, std::false_type) {
+                measure([&fun](int) { return fun(); }, std::true_type());
+            }
+
+            template <typename Fun>
+            void measure(Fun&& fun, std::true_type) {
+                Detail::optimizer_barrier();
+                impl->start();
+                for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
+                impl->finish();
+                Detail::optimizer_barrier();
+            }
+
+            Detail::ChronometerConcept* impl;
+            int k;
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_chronometer.hpp
+// start catch_environment.hpp
+
+// Environment information
+
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct EnvironmentEstimate {
+            Duration mean;
+            OutlierClassification outliers;
+
+            template <typename Duration2>
+            operator EnvironmentEstimate<Duration2>() const {
+                return { mean, outliers };
+            }
+        };
+        template <typename Clock>
+        struct Environment {
+            using clock_type = Clock;
+            EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
+            EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_environment.hpp
+// start catch_execution_plan.hpp
+
+ // Execution plan
+
+
+// start catch_benchmark_function.hpp
+
+ // Dumb std::function implementation for consistent call overhead
+
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+#include <memory>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename T>
+            using Decay = typename std::decay<T>::type;
+            template <typename T, typename U>
+            struct is_related
+                : std::is_same<Decay<T>, Decay<U>> {};
+
+            /// We need to reinvent std::function because every piece of code that might add overhead
+            /// in a measurement context needs to have consistent performance characteristics so that we
+            /// can account for it in the measurement.
+            /// Implementations of std::function with optimizations that aren't always applicable, like
+            /// small buffer optimizations, are not uncommon.
+            /// This is effectively an implementation of std::function without any such optimizations;
+            /// it may be slow, but it is consistently slow.
+            struct BenchmarkFunction {
+            private:
+                struct callable {
+                    virtual void call(Chronometer meter) const = 0;
+                    virtual callable* clone() const = 0;
+                    virtual ~callable() = default;
+                };
+                template <typename Fun>
+                struct model : public callable {
+                    model(Fun&& fun) : fun(std::move(fun)) {}
+                    model(Fun const& fun) : fun(fun) {}
+
+                    model<Fun>* clone() const override { return new model<Fun>(*this); }
+
+                    void call(Chronometer meter) const override {
+                        call(meter, is_callable<Fun(Chronometer)>());
+                    }
+                    void call(Chronometer meter, std::true_type) const {
+                        fun(meter);
+                    }
+                    void call(Chronometer meter, std::false_type) const {
+                        meter.measure(fun);
+                    }
+
+                    Fun fun;
+                };
+
+                struct do_nothing { void operator()() const {} };
+
+                template <typename T>
+                BenchmarkFunction(model<T>* c) : f(c) {}
+
+            public:
+                BenchmarkFunction()
+                    : f(new model<do_nothing>{ {} }) {}
+
+                template <typename Fun,
+                    typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
+                    BenchmarkFunction(Fun&& fun)
+                    : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
+
+                BenchmarkFunction(BenchmarkFunction&& that)
+                    : f(std::move(that.f)) {}
+
+                BenchmarkFunction(BenchmarkFunction const& that)
+                    : f(that.f->clone()) {}
+
+                BenchmarkFunction& operator=(BenchmarkFunction&& that) {
+                    f = std::move(that.f);
+                    return *this;
+                }
+
+                BenchmarkFunction& operator=(BenchmarkFunction const& that) {
+                    f.reset(that.f->clone());
+                    return *this;
+                }
+
+                void operator()(Chronometer meter) const { f->call(meter); }
+
+            private:
+                std::unique_ptr<callable> f;
+            };
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_benchmark_function.hpp
+// start catch_repeat.hpp
+
+// repeat algorithm
+
+
+#include <type_traits>
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Fun>
+            struct repeater {
+                void operator()(int k) const {
+                    for (int i = 0; i < k; ++i) {
+                        fun();
+                    }
+                }
+                Fun fun;
+            };
+            template <typename Fun>
+            repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
+                return { std::forward<Fun>(fun) };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_repeat.hpp
+// start catch_run_for_at_least.hpp
+
+// Run a function for a minimum amount of time
+
+
+// start catch_measure.hpp
+
+// Measure
+
+
+// start catch_timing.hpp
+
+// Timing
+
+
+#include <tuple>
+#include <type_traits>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration, typename Result>
+        struct Timing {
+            Duration elapsed;
+            Result result;
+            int iterations;
+        };
+        template <typename Clock, typename Func, typename... Args>
+        using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_timing.hpp
+#include <utility>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock, typename Fun, typename... Args>
+            TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
+                auto start = Clock::now();
+                auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
+                auto end = Clock::now();
+                auto delta = end - start;
+                return { delta, std::forward<decltype(r)>(r), 1 };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_measure.hpp
+#include <utility>
+#include <type_traits>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
+                return Detail::measure<Clock>(fun, iters);
+            }
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
+                Detail::ChronometerModel<Clock> meter;
+                auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
+
+                return { meter.elapsed(), std::move(result), iters };
+            }
+
+            template <typename Clock, typename Fun>
+            using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
+
+            struct optimized_away_error : std::exception {
+                const char* what() const noexcept override {
+                    return "could not measure benchmark, maybe it was optimized away";
+                }
+            };
+
+            template <typename Clock, typename Fun>
+            TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
+                auto iters = seed;
+                while (iters < (1 << 30)) {
+                    auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
+
+                    if (Timing.elapsed >= how_long) {
+                        return { Timing.elapsed, std::move(Timing.result), iters };
+                    }
+                    iters *= 2;
+                }
+                Catch::throw_exception(optimized_away_error{});
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_run_for_at_least.hpp
+#include <algorithm>
+#include <iterator>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct ExecutionPlan {
+            int iterations_per_sample;
+            Duration estimated_duration;
+            Detail::BenchmarkFunction benchmark;
+            Duration warmup_time;
+            int warmup_iterations;
+
+            template <typename Duration2>
+            operator ExecutionPlan<Duration2>() const {
+                return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
+            }
+
+            template <typename Clock>
+            std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
+                // warmup a bit
+                Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
+
+                std::vector<FloatDuration<Clock>> times;
+                times.reserve(cfg.benchmarkSamples());
+                std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
+                    Detail::ChronometerModel<Clock> model;
+                    this->benchmark(Chronometer(model, iterations_per_sample));
+                    auto sample_time = model.elapsed() - env.clock_cost.mean;
+                    if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
+                    return sample_time / iterations_per_sample;
+                });
+                return times;
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_execution_plan.hpp
+// start catch_estimate_clock.hpp
+
+ // Environment measurement
+
+
+// start catch_stats.hpp
+
+// Statistical analysis tools
+
+
+#include <algorithm>
+#include <functional>
+#include <vector>
+#include <iterator>
+#include <numeric>
+#include <tuple>
+#include <cmath>
+#include <utility>
+#include <cstddef>
+#include <random>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            using sample = std::vector<double>;
+
+            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
+
+            template <typename Iterator>
+            OutlierClassification classify_outliers(Iterator first, Iterator last) {
+                std::vector<double> copy(first, last);
+
+                auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
+                auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
+                auto iqr = q3 - q1;
+                auto los = q1 - (iqr * 3.);
+                auto lom = q1 - (iqr * 1.5);
+                auto him = q3 + (iqr * 1.5);
+                auto his = q3 + (iqr * 3.);
+
+                OutlierClassification o;
+                for (; first != last; ++first) {
+                    auto&& t = *first;
+                    if (t < los) ++o.low_severe;
+                    else if (t < lom) ++o.low_mild;
+                    else if (t > his) ++o.high_severe;
+                    else if (t > him) ++o.high_mild;
+                    ++o.samples_seen;
+                }
+                return o;
+            }
+
+            template <typename Iterator>
+            double mean(Iterator first, Iterator last) {
+                auto count = last - first;
+                double sum = std::accumulate(first, last, 0.);
+                return sum / count;
+            }
+
+            template <typename URng, typename Iterator, typename Estimator>
+            sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
+                auto n = last - first;
+                std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
+
+                sample out;
+                out.reserve(resamples);
+                std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
+                    std::vector<double> resampled;
+                    resampled.reserve(n);
+                    std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
+                    return estimator(resampled.begin(), resampled.end());
+                });
+                std::sort(out.begin(), out.end());
+                return out;
+            }
+
+            template <typename Estimator, typename Iterator>
+            sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
+                auto n = last - first;
+                auto second = std::next(first);
+                sample results;
+                results.reserve(n);
+
+                for (auto it = first; it != last; ++it) {
+                    std::iter_swap(it, first);
+                    results.push_back(estimator(second, last));
+                }
+
+                return results;
+            }
+
+            inline double normal_cdf(double x) {
+                return std::erfc(-x / std::sqrt(2.0)) / 2.0;
+            }
+
+            double erfc_inv(double x);
+
+            double normal_quantile(double p);
+
+            template <typename Iterator, typename Estimator>
+            Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
+                auto n_samples = last - first;
+
+                double point = estimator(first, last);
+                // Degenerate case with a single sample
+                if (n_samples == 1) return { point, point, point, confidence_level };
+
+                sample jack = jackknife(estimator, first, last);
+                double jack_mean = mean(jack.begin(), jack.end());
+                double sum_squares, sum_cubes;
+                std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
+                    auto d = jack_mean - x;
+                    auto d2 = d * d;
+                    auto d3 = d2 * d;
+                    return { sqcb.first + d2, sqcb.second + d3 };
+                });
+
+                double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
+                int n = static_cast<int>(resample.size());
+                double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
+                // degenerate case with uniform samples
+                if (prob_n == 0) return { point, point, point, confidence_level };
+
+                double bias = normal_quantile(prob_n);
+                double z1 = normal_quantile((1. - confidence_level) / 2.);
+
+                auto cumn = [n](double x) -> int {
+                    return std::lround(normal_cdf(x) * n); };
+                auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
+                double b1 = bias + z1;
+                double b2 = bias - z1;
+                double a1 = a(b1);
+                double a2 = a(b2);
+                auto lo = (std::max)(cumn(a1), 0);
+                auto hi = (std::min)(cumn(a2), n - 1);
+
+                return { point, resample[lo], resample[hi], confidence_level };
+            }
+
+            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
+
+            struct bootstrap_analysis {
+                Estimate<double> mean;
+                Estimate<double> standard_deviation;
+                double outlier_variance;
+            };
+
+            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_stats.hpp
+#include <algorithm>
+#include <iterator>
+#include <tuple>
+#include <vector>
+#include <cmath>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Clock>
+            std::vector<double> resolution(int k) {
+                std::vector<TimePoint<Clock>> times;
+                times.reserve(k + 1);
+                std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
+
+                std::vector<double> deltas;
+                deltas.reserve(k);
+                std::transform(std::next(times.begin()), times.end(), times.begin(),
+                    std::back_inserter(deltas),
+                    [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
+
+                return deltas;
+            }
+
+            const auto warmup_iterations = 10000;
+            const auto warmup_time = std::chrono::milliseconds(100);
+            const auto minimum_ticks = 1000;
+            const auto warmup_seed = 10000;
+            const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
+            const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
+            const auto clock_cost_estimation_tick_limit = 100000;
+            const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
+            const auto clock_cost_estimation_iterations = 10000;
+
+            template <typename Clock>
+            int warmup() {
+                return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
+                    .iterations;
+            }
+            template <typename Clock>
+            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
+                auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
+                    .result;
+                return {
+                    FloatDuration<Clock>(mean(r.begin(), r.end())),
+                    classify_outliers(r.begin(), r.end()),
+                };
+            }
+            template <typename Clock>
+            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
+                auto time_limit = (std::min)(
+                    resolution * clock_cost_estimation_tick_limit,
+                    FloatDuration<Clock>(clock_cost_estimation_time_limit));
+                auto time_clock = [](int k) {
+                    return Detail::measure<Clock>([k] {
+                        for (int i = 0; i < k; ++i) {
+                            volatile auto ignored = Clock::now();
+                            (void)ignored;
+                        }
+                    }).elapsed;
+                };
+                time_clock(1);
+                int iters = clock_cost_estimation_iterations;
+                auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
+                std::vector<double> times;
+                int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
+                times.reserve(nsamples);
+                std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
+                    return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
+                });
+                return {
+                    FloatDuration<Clock>(mean(times.begin(), times.end())),
+                    classify_outliers(times.begin(), times.end()),
+                };
+            }
+
+            template <typename Clock>
+            Environment<FloatDuration<Clock>> measure_environment() {
+                static Environment<FloatDuration<Clock>>* env = nullptr;
+                if (env) {
+                    return *env;
+                }
+
+                auto iters = Detail::warmup<Clock>();
+                auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
+                auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
+
+                env = new Environment<FloatDuration<Clock>>{ resolution, cost };
+                return *env;
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_estimate_clock.hpp
+// start catch_analyse.hpp
+
+ // Run and analyse one benchmark
+
+
+// start catch_sample_analysis.hpp
+
+// Benchmark results
+
+
+#include <algorithm>
+#include <vector>
+#include <string>
+#include <iterator>
+
+namespace Catch {
+    namespace Benchmark {
+        template <typename Duration>
+        struct SampleAnalysis {
+            std::vector<Duration> samples;
+            Estimate<Duration> mean;
+            Estimate<Duration> standard_deviation;
+            OutlierClassification outliers;
+            double outlier_variance;
+
+            template <typename Duration2>
+            operator SampleAnalysis<Duration2>() const {
+                std::vector<Duration2> samples2;
+                samples2.reserve(samples.size());
+                std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
+                return {
+                    std::move(samples2),
+                    mean,
+                    standard_deviation,
+                    outliers,
+                    outlier_variance,
+                };
+            }
+        };
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_sample_analysis.hpp
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename Duration, typename Iterator>
+            SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
+                if (!cfg.benchmarkNoAnalysis()) {
+                    std::vector<double> samples;
+                    samples.reserve(last - first);
+                    std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
+
+                    auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
+                    auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
+
+                    auto wrap_estimate = [](Estimate<double> e) {
+                        return Estimate<Duration> {
+                            Duration(e.point),
+                                Duration(e.lower_bound),
+                                Duration(e.upper_bound),
+                                e.confidence_interval,
+                        };
+                    };
+                    std::vector<Duration> samples2;
+                    samples2.reserve(samples.size());
+                    std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
+                    return {
+                        std::move(samples2),
+                        wrap_estimate(analysis.mean),
+                        wrap_estimate(analysis.standard_deviation),
+                        outliers,
+                        analysis.outlier_variance,
+                    };
+                } else {
+                    std::vector<Duration> samples;
+                    samples.reserve(last - first);
+
+                    Duration mean = Duration(0);
+                    int i = 0;
+                    for (auto it = first; it < last; ++it, ++i) {
+                        samples.push_back(Duration(*it));
+                        mean += Duration(*it);
+                    }
+                    mean /= i;
+
+                    return {
+                        std::move(samples),
+                        Estimate<Duration>{mean, mean, mean, 0.0},
+                        Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
+                        OutlierClassification{},
+                        0.0
+                    };
+                }
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+// end catch_analyse.hpp
+#include <algorithm>
+#include <functional>
+#include <string>
+#include <vector>
+#include <cmath>
+
+namespace Catch {
+    namespace Benchmark {
+        struct Benchmark {
+            Benchmark(std::string &&name)
+                : name(std::move(name)) {}
+
+            template <class FUN>
+            Benchmark(std::string &&name, FUN &&func)
+                : fun(std::move(func)), name(std::move(name)) {}
+
+            template <typename Clock>
+            ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
+                auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
+                auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
+                auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
+                int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
+                return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
+            }
+
+            template <typename Clock = default_clock>
+            void run() {
+                IConfigPtr cfg = getCurrentContext().getConfig();
+
+                auto env = Detail::measure_environment<Clock>();
+
+                getResultCapture().benchmarkPreparing(name);
+                CATCH_TRY{
+                    auto plan = user_code([&] {
+                        return prepare<Clock>(*cfg, env);
+                    });
+
+                    BenchmarkInfo info {
+                        name,
+                        plan.estimated_duration.count(),
+                        plan.iterations_per_sample,
+                        cfg->benchmarkSamples(),
+                        cfg->benchmarkResamples(),
+                        env.clock_resolution.mean.count(),
+                        env.clock_cost.mean.count()
+                    };
+
+                    getResultCapture().benchmarkStarting(info);
+
+                    auto samples = user_code([&] {
+                        return plan.template run<Clock>(*cfg, env);
+                    });
+
+                    auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
+                    BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
+                    getResultCapture().benchmarkEnded(stats);
+
+                } CATCH_CATCH_ALL{
+                    if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
+                        std::rethrow_exception(std::current_exception());
+                }
+            }
+
+            // sets lambda to be used in fun *and* executes benchmark!
+            template <typename Fun,
+                typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
+                Benchmark & operator=(Fun func) {
+                fun = Detail::BenchmarkFunction(func);
+                run();
+                return *this;
+            }
+
+            explicit operator bool() {
+                return true;
+            }
+
+        private:
+            Detail::BenchmarkFunction fun;
+            std::string name;
+        };
+    }
+} // namespace Catch
+
+#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
+#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
+
+#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
+    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
+        BenchmarkName = [&](int benchmarkIndex)
+
+#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
+    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
+        BenchmarkName = [&]
+
+// end catch_benchmark.hpp
+// start catch_constructor.hpp
+
+// Constructor and destructor helpers
+
+
+#include <type_traits>
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+            template <typename T, bool Destruct>
+            struct ObjectStorage
+            {
+                using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
+
+                ObjectStorage() : data() {}
+
+                ObjectStorage(const ObjectStorage& other)
+                {
+                    new(&data) T(other.stored_object());
+                }
+
+                ObjectStorage(ObjectStorage&& other)
+                {
+                    new(&data) T(std::move(other.stored_object()));
+                }
+
+                ~ObjectStorage() { destruct_on_exit<T>(); }
+
+                template <typename... Args>
+                void construct(Args&&... args)
+                {
+                    new (&data) T(std::forward<Args>(args)...);
+                }
+
+                template <bool AllowManualDestruction = !Destruct>
+                typename std::enable_if<AllowManualDestruction>::type destruct()
+                {
+                    stored_object().~T();
+                }
+
+            private:
+                // If this is a constructor benchmark, destruct the underlying object
+                template <typename U>
+                void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
+                // Otherwise, don't
+                template <typename U>
+                void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
+
+                T& stored_object() {
+                    return *static_cast<T*>(static_cast<void*>(&data));
+                }
+
+                T const& stored_object() const {
+                    return *static_cast<T*>(static_cast<void*>(&data));
+                }
+
+                TStorage data;
+            };
+        }
+
+        template <typename T>
+        using storage_for = Detail::ObjectStorage<T, true>;
+
+        template <typename T>
+        using destructable_object = Detail::ObjectStorage<T, false>;
+    }
+}
+
+// end catch_constructor.hpp
+// end catch_benchmarking_all.hpp
+#endif
+
+#endif // ! CATCH_CONFIG_IMPL_ONLY
+
+#ifdef CATCH_IMPL
+// start catch_impl.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// Keep these here for external reporters
+// start catch_test_case_tracker.h
+
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+namespace TestCaseTracking {
+
+    struct NameAndLocation {
+        std::string name;
+        SourceLineInfo location;
+
+        NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
+        friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
+            return lhs.name == rhs.name
+                && lhs.location == rhs.location;
+        }
+    };
+
+    class ITracker;
+
+    using ITrackerPtr = std::shared_ptr<ITracker>;
+
+    class  ITracker {
+        NameAndLocation m_nameAndLocation;
+
+    public:
+        ITracker(NameAndLocation const& nameAndLoc) :
+            m_nameAndLocation(nameAndLoc)
+        {}
+
+        // static queries
+        NameAndLocation const& nameAndLocation() const {
+            return m_nameAndLocation;
+        }
+
+        virtual ~ITracker();
+
+        // dynamic queries
+        virtual bool isComplete() const = 0; // Successfully completed or failed
+        virtual bool isSuccessfullyCompleted() const = 0;
+        virtual bool isOpen() const = 0; // Started but not complete
+        virtual bool hasChildren() const = 0;
+        virtual bool hasStarted() const = 0;
+
+        virtual ITracker& parent() = 0;
+
+        // actions
+        virtual void close() = 0; // Successfully complete
+        virtual void fail() = 0;
+        virtual void markAsNeedingAnotherRun() = 0;
+
+        virtual void addChild( ITrackerPtr const& child ) = 0;
+        virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
+        virtual void openChild() = 0;
+
+        // Debug/ checking
+        virtual bool isSectionTracker() const = 0;
+        virtual bool isGeneratorTracker() const = 0;
+    };
+
+    class TrackerContext {
+
+        enum RunState {
+            NotStarted,
+            Executing,
+            CompletedCycle
+        };
+
+        ITrackerPtr m_rootTracker;
+        ITracker* m_currentTracker = nullptr;
+        RunState m_runState = NotStarted;
+
+    public:
+
+        ITracker& startRun();
+        void endRun();
+
+        void startCycle();
+        void completeCycle();
+
+        bool completedCycle() const;
+        ITracker& currentTracker();
+        void setCurrentTracker( ITracker* tracker );
+    };
+
+    class TrackerBase : public ITracker {
+    protected:
+        enum CycleState {
+            NotStarted,
+            Executing,
+            ExecutingChildren,
+            NeedsAnotherRun,
+            CompletedSuccessfully,
+            Failed
+        };
+
+        using Children = std::vector<ITrackerPtr>;
+        TrackerContext& m_ctx;
+        ITracker* m_parent;
+        Children m_children;
+        CycleState m_runState = NotStarted;
+
+    public:
+        TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
+
+        bool isComplete() const override;
+        bool isSuccessfullyCompleted() const override;
+        bool isOpen() const override;
+        bool hasChildren() const override;
+        bool hasStarted() const override {
+            return m_runState != NotStarted;
+        }
+
+        void addChild( ITrackerPtr const& child ) override;
+
+        ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
+        ITracker& parent() override;
+
+        void openChild() override;
+
+        bool isSectionTracker() const override;
+        bool isGeneratorTracker() const override;
+
+        void open();
+
+        void close() override;
+        void fail() override;
+        void markAsNeedingAnotherRun() override;
+
+    private:
+        void moveToParent();
+        void moveToThis();
+    };
+
+    class SectionTracker : public TrackerBase {
+        std::vector<std::string> m_filters;
+        std::string m_trimmed_name;
+    public:
+        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
+
+        bool isSectionTracker() const override;
+
+        bool isComplete() const override;
+
+        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
+
+        void tryOpen();
+
+        void addInitialFilters( std::vector<std::string> const& filters );
+        void addNextFilters( std::vector<std::string> const& filters );
+        //! Returns filters active in this tracker
+        std::vector<std::string> const& getFilters() const;
+        //! Returns whitespace-trimmed name of the tracked section
+        std::string const& trimmedName() const;
+    };
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+
+} // namespace Catch
+
+// end catch_test_case_tracker.h
+
+// start catch_leak_detector.h
+
+namespace Catch {
+
+    struct LeakDetector {
+        LeakDetector();
+        ~LeakDetector();
+    };
+
+}
+// end catch_leak_detector.h
+// Cpp files will be included in the single-header file here
+// start catch_stats.cpp
+
+// Statistical analysis tools
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+
+#include <cassert>
+#include <random>
+
+#if defined(CATCH_CONFIG_USE_ASYNC)
+#include <future>
+#endif
+
+namespace {
+    double erf_inv(double x) {
+        // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
+        double w, p;
+
+        w = -log((1.0 - x) * (1.0 + x));
+
+        if (w < 6.250000) {
+            w = w - 3.125000;
+            p = -3.6444120640178196996e-21;
+            p = -1.685059138182016589e-19 + p * w;
+            p = 1.2858480715256400167e-18 + p * w;
+            p = 1.115787767802518096e-17 + p * w;
+            p = -1.333171662854620906e-16 + p * w;
+            p = 2.0972767875968561637e-17 + p * w;
+            p = 6.6376381343583238325e-15 + p * w;
+            p = -4.0545662729752068639e-14 + p * w;
+            p = -8.1519341976054721522e-14 + p * w;
+            p = 2.6335093153082322977e-12 + p * w;
+            p = -1.2975133253453532498e-11 + p * w;
+            p = -5.4154120542946279317e-11 + p * w;
+            p = 1.051212273321532285e-09 + p * w;
+            p = -4.1126339803469836976e-09 + p * w;
+            p = -2.9070369957882005086e-08 + p * w;
+            p = 4.2347877827932403518e-07 + p * w;
+            p = -1.3654692000834678645e-06 + p * w;
+            p = -1.3882523362786468719e-05 + p * w;
+            p = 0.0001867342080340571352 + p * w;
+            p = -0.00074070253416626697512 + p * w;
+            p = -0.0060336708714301490533 + p * w;
+            p = 0.24015818242558961693 + p * w;
+            p = 1.6536545626831027356 + p * w;
+        } else if (w < 16.000000) {
+            w = sqrt(w) - 3.250000;
+            p = 2.2137376921775787049e-09;
+            p = 9.0756561938885390979e-08 + p * w;
+            p = -2.7517406297064545428e-07 + p * w;
+            p = 1.8239629214389227755e-08 + p * w;
+            p = 1.5027403968909827627e-06 + p * w;
+            p = -4.013867526981545969e-06 + p * w;
+            p = 2.9234449089955446044e-06 + p * w;
+            p = 1.2475304481671778723e-05 + p * w;
+            p = -4.7318229009055733981e-05 + p * w;
+            p = 6.8284851459573175448e-05 + p * w;
+            p = 2.4031110387097893999e-05 + p * w;
+            p = -0.0003550375203628474796 + p * w;
+            p = 0.00095328937973738049703 + p * w;
+            p = -0.0016882755560235047313 + p * w;
+            p = 0.0024914420961078508066 + p * w;
+            p = -0.0037512085075692412107 + p * w;
+            p = 0.005370914553590063617 + p * w;
+            p = 1.0052589676941592334 + p * w;
+            p = 3.0838856104922207635 + p * w;
+        } else {
+            w = sqrt(w) - 5.000000;
+            p = -2.7109920616438573243e-11;
+            p = -2.5556418169965252055e-10 + p * w;
+            p = 1.5076572693500548083e-09 + p * w;
+            p = -3.7894654401267369937e-09 + p * w;
+            p = 7.6157012080783393804e-09 + p * w;
+            p = -1.4960026627149240478e-08 + p * w;
+            p = 2.9147953450901080826e-08 + p * w;
+            p = -6.7711997758452339498e-08 + p * w;
+            p = 2.2900482228026654717e-07 + p * w;
+            p = -9.9298272942317002539e-07 + p * w;
+            p = 4.5260625972231537039e-06 + p * w;
+            p = -1.9681778105531670567e-05 + p * w;
+            p = 7.5995277030017761139e-05 + p * w;
+            p = -0.00021503011930044477347 + p * w;
+            p = -0.00013871931833623122026 + p * w;
+            p = 1.0103004648645343977 + p * w;
+            p = 4.8499064014085844221 + p * w;
+        }
+        return p * x;
+    }
+
+    double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
+        auto m = Catch::Benchmark::Detail::mean(first, last);
+        double variance = std::accumulate(first, last, 0., [m](double a, double b) {
+            double diff = b - m;
+            return a + diff * diff;
+            }) / (last - first);
+            return std::sqrt(variance);
+    }
+
+}
+
+namespace Catch {
+    namespace Benchmark {
+        namespace Detail {
+
+            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+                auto count = last - first;
+                double idx = (count - 1) * k / static_cast<double>(q);
+                int j = static_cast<int>(idx);
+                double g = idx - j;
+                std::nth_element(first, first + j, last);
+                auto xj = first[j];
+                if (g == 0) return xj;
+
+                auto xj1 = *std::min_element(first + (j + 1), last);
+                return xj + g * (xj1 - xj);
+            }
+
+            double erfc_inv(double x) {
+                return erf_inv(1.0 - x);
+            }
+
+            double normal_quantile(double p) {
+                static const double ROOT_TWO = std::sqrt(2.0);
+
+                double result = 0.0;
+                assert(p >= 0 && p <= 1);
+                if (p < 0 || p > 1) {
+                    return result;
+                }
+
+                result = -erfc_inv(2.0 * p);
+                // result *= normal distribution standard deviation (1.0) * sqrt(2)
+                result *= /*sd * */ ROOT_TWO;
+                // result += normal disttribution mean (0)
+                return result;
+            }
+
+            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
+                double sb = stddev.point;
+                double mn = mean.point / n;
+                double mg_min = mn / 2.;
+                double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
+                double sg2 = sg * sg;
+                double sb2 = sb * sb;
+
+                auto c_max = [n, mn, sb2, sg2](double x) -> double {
+                    double k = mn - x;
+                    double d = k * k;
+                    double nd = n * d;
+                    double k0 = -n * nd;
+                    double k1 = sb2 - n * sg2 + nd;
+                    double det = k1 * k1 - 4 * sg2 * k0;
+                    return (int)(-2. * k0 / (k1 + std::sqrt(det)));
+                };
+
+                auto var_out = [n, sb2, sg2](double c) {
+                    double nc = n - c;
+                    return (nc / n) * (sb2 - nc * sg2);
+                };
+
+                return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
+            }
+
+            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+                CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
+                CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+                static std::random_device entropy;
+                CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+
+                auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
+
+                auto mean = &Detail::mean<std::vector<double>::iterator>;
+                auto stddev = &standard_deviation;
+
+#if defined(CATCH_CONFIG_USE_ASYNC)
+                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+                    auto seed = entropy();
+                    return std::async(std::launch::async, [=] {
+                        std::mt19937 rng(seed);
+                        auto resampled = resample(rng, n_resamples, first, last, f);
+                        return bootstrap(confidence_level, first, last, resampled, f);
+                    });
+                };
+
+                auto mean_future = Estimate(mean);
+                auto stddev_future = Estimate(stddev);
+
+                auto mean_estimate = mean_future.get();
+                auto stddev_estimate = stddev_future.get();
+#else
+                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+                    auto seed = entropy();
+                    std::mt19937 rng(seed);
+                    auto resampled = resample(rng, n_resamples, first, last, f);
+                    return bootstrap(confidence_level, first, last, resampled, f);
+                };
+
+                auto mean_estimate = Estimate(mean);
+                auto stddev_estimate = Estimate(stddev);
+#endif // CATCH_USE_ASYNC
+
+                double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
+
+                return { mean_estimate, stddev_estimate, outlier_variance };
+            }
+        } // namespace Detail
+    } // namespace Benchmark
+} // namespace Catch
+
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+// end catch_stats.cpp
+// start catch_approx.cpp
+
+#include <cmath>
+#include <limits>
+
+namespace {
+
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+    return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+}
+
+}
+
+namespace Catch {
+namespace Detail {
+
+    Approx::Approx ( double value )
+    :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+        m_margin( 0.0 ),
+        m_scale( 0.0 ),
+        m_value( value )
+    {}
+
+    Approx Approx::custom() {
+        return Approx( 0 );
+    }
+
+    Approx Approx::operator-() const {
+        auto temp(*this);
+        temp.m_value = -temp.m_value;
+        return temp;
+    }
+
+    std::string Approx::toString() const {
+        ReusableStringStream rss;
+        rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
+        return rss.str();
+    }
+
+    bool Approx::equalityComparisonImpl(const double other) const {
+        // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
+        // Thanks to Richard Harris for his help refining the scaled margin value
+        return marginComparison(m_value, other, m_margin)
+            || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
+    }
+
+    void Approx::setMargin(double newMargin) {
+        CATCH_ENFORCE(newMargin >= 0,
+            "Invalid Approx::margin: " << newMargin << '.'
+            << " Approx::Margin has to be non-negative.");
+        m_margin = newMargin;
+    }
+
+    void Approx::setEpsilon(double newEpsilon) {
+        CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
+            "Invalid Approx::epsilon: " << newEpsilon << '.'
+            << " Approx::epsilon has to be in [0, 1]");
+        m_epsilon = newEpsilon;
+    }
+
+} // end namespace Detail
+
+namespace literals {
+    Detail::Approx operator "" _a(long double val) {
+        return Detail::Approx(val);
+    }
+    Detail::Approx operator "" _a(unsigned long long val) {
+        return Detail::Approx(val);
+    }
+} // end namespace literals
+
+std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
+    return value.toString();
+}
+
+} // end namespace Catch
+// end catch_approx.cpp
+// start catch_assertionhandler.cpp
+
+// start catch_debugger.h
+
+namespace Catch {
+    bool isDebuggerActive();
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+    #if defined(__i386__) || defined(__x86_64__)
+        #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
+    #elif defined(__aarch64__)
+        #define CATCH_TRAP()  __asm__(".inst 0xd4200000")
+    #endif
+
+#elif defined(CATCH_PLATFORM_IPHONE)
+
+    // use inline assembler
+    #if defined(__i386__) || defined(__x86_64__)
+        #define CATCH_TRAP()  __asm__("int $3")
+    #elif defined(__aarch64__)
+        #define CATCH_TRAP()  __asm__(".inst 0xd4200000")
+    #elif defined(__arm__) && !defined(__thumb__)
+        #define CATCH_TRAP()  __asm__(".inst 0xe7f001f0")
+    #elif defined(__arm__) &&  defined(__thumb__)
+        #define CATCH_TRAP()  __asm__(".inst 0xde01")
+    #endif
+
+#elif defined(CATCH_PLATFORM_LINUX)
+    // If we can use inline assembler, do it because this allows us to break
+    // directly at the location of the failing check instead of breaking inside
+    // raise() called from it, i.e. one stack frame below.
+    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
+        #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
+    #else // Fall back to the generic way.
+        #include <signal.h>
+
+        #define CATCH_TRAP() raise(SIGTRAP)
+    #endif
+#elif defined(_MSC_VER)
+    #define CATCH_TRAP() __debugbreak()
+#elif defined(__MINGW32__)
+    extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+    #define CATCH_TRAP() DebugBreak()
+#endif
+
+#ifndef CATCH_BREAK_INTO_DEBUGGER
+    #ifdef CATCH_TRAP
+        #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
+    #else
+        #define CATCH_BREAK_INTO_DEBUGGER() []{}()
+    #endif
+#endif
+
+// end catch_debugger.h
+// start catch_run_context.h
+
+// start catch_fatal_condition.h
+
+#include <cassert>
+
+namespace Catch {
+
+    // Wrapper for platform-specific fatal error (signals/SEH) handlers
+    //
+    // Tries to be cooperative with other handlers, and not step over
+    // other handlers. This means that unknown structured exceptions
+    // are passed on, previous signal handlers are called, and so on.
+    //
+    // Can only be instantiated once, and assumes that once a signal
+    // is caught, the binary will end up terminating. Thus, there
+    class FatalConditionHandler {
+        bool m_started = false;
+
+        // Install/disengage implementation for specific platform.
+        // Should be if-defed to work on current platform, can assume
+        // engage-disengage 1:1 pairing.
+        void engage_platform();
+        void disengage_platform();
+    public:
+        // Should also have platform-specific implementations as needed
+        FatalConditionHandler();
+        ~FatalConditionHandler();
+
+        void engage() {
+            assert(!m_started && "Handler cannot be installed twice.");
+            m_started = true;
+            engage_platform();
+        }
+
+        void disengage() {
+            assert(m_started && "Handler cannot be uninstalled without being installed first");
+            m_started = false;
+            disengage_platform();
+        }
+    };
+
+    //! Simple RAII guard for (dis)engaging the FatalConditionHandler
+    class FatalConditionHandlerGuard {
+        FatalConditionHandler* m_handler;
+    public:
+        FatalConditionHandlerGuard(FatalConditionHandler* handler):
+            m_handler(handler) {
+            m_handler->engage();
+        }
+        ~FatalConditionHandlerGuard() {
+            m_handler->disengage();
+        }
+    };
+
+} // end namespace Catch
+
+// end catch_fatal_condition.h
+#include <string>
+
+namespace Catch {
+
+    struct IMutableContext;
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class RunContext : public IResultCapture, public IRunner {
+
+    public:
+        RunContext( RunContext const& ) = delete;
+        RunContext& operator =( RunContext const& ) = delete;
+
+        explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
+
+        ~RunContext() override;
+
+        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
+        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
+
+        Totals runTest(TestCase const& testCase);
+
+        IConfigPtr config() const;
+        IStreamingReporter& reporter() const;
+
+    public: // IResultCapture
+
+        // Assertion handlers
+        void handleExpr
+                (   AssertionInfo const& info,
+                    ITransientExpression const& expr,
+                    AssertionReaction& reaction ) override;
+        void handleMessage
+                (   AssertionInfo const& info,
+                    ResultWas::OfType resultType,
+                    StringRef const& message,
+                    AssertionReaction& reaction ) override;
+        void handleUnexpectedExceptionNotThrown
+                (   AssertionInfo const& info,
+                    AssertionReaction& reaction ) override;
+        void handleUnexpectedInflightException
+                (   AssertionInfo const& info,
+                    std::string const& message,
+                    AssertionReaction& reaction ) override;
+        void handleIncomplete
+                (   AssertionInfo const& info ) override;
+        void handleNonExpr
+                (   AssertionInfo const &info,
+                    ResultWas::OfType resultType,
+                    AssertionReaction &reaction ) override;
+
+        bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
+
+        void sectionEnded( SectionEndInfo const& endInfo ) override;
+        void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
+
+        auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing( std::string const& name ) override;
+        void benchmarkStarting( BenchmarkInfo const& info ) override;
+        void benchmarkEnded( BenchmarkStats<> const& stats ) override;
+        void benchmarkFailed( std::string const& error ) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+        void pushScopedMessage( MessageInfo const& message ) override;
+        void popScopedMessage( MessageInfo const& message ) override;
+
+        void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
+
+        std::string getCurrentTestName() const override;
+
+        const AssertionResult* getLastResult() const override;
+
+        void exceptionEarlyReported() override;
+
+        void handleFatalErrorCondition( StringRef message ) override;
+
+        bool lastAssertionPassed() override;
+
+        void assertionPassed() override;
+
+    public:
+        // !TBD We need to do this another way!
+        bool aborting() const final;
+
+    private:
+
+        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
+        void invokeActiveTestCase();
+
+        void resetAssertionInfo();
+        bool testForMissingAssertions( Counts& assertions );
+
+        void assertionEnded( AssertionResult const& result );
+        void reportExpr
+                (   AssertionInfo const &info,
+                    ResultWas::OfType resultType,
+                    ITransientExpression const *expr,
+                    bool negated );
+
+        void populateReaction( AssertionReaction& reaction );
+
+    private:
+
+        void handleUnfinishedSections();
+
+        TestRunInfo m_runInfo;
+        IMutableContext& m_context;
+        TestCase const* m_activeTestCase = nullptr;
+        ITracker* m_testCaseTracker = nullptr;
+        Option<AssertionResult> m_lastResult;
+
+        IConfigPtr m_config;
+        Totals m_totals;
+        IStreamingReporterPtr m_reporter;
+        std::vector<MessageInfo> m_messages;
+        std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
+        AssertionInfo m_lastAssertionInfo;
+        std::vector<SectionEndInfo> m_unfinishedSections;
+        std::vector<ITracker*> m_activeSections;
+        TrackerContext m_trackerContext;
+        FatalConditionHandler m_fatalConditionhandler;
+        bool m_lastAssertionPassed = false;
+        bool m_shouldReportUnexpected = true;
+        bool m_includeSuccessfulResults;
+    };
+
+    void seedRng(IConfig const& config);
+    unsigned int rngSeed();
+} // end namespace Catch
+
+// end catch_run_context.h
+namespace Catch {
+
+    namespace {
+        auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
+            expr.streamReconstructedExpression( os );
+            return os;
+        }
+    }
+
+    LazyExpression::LazyExpression( bool isNegated )
+    :   m_isNegated( isNegated )
+    {}
+
+    LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
+
+    LazyExpression::operator bool() const {
+        return m_transientExpression != nullptr;
+    }
+
+    auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
+        if( lazyExpr.m_isNegated )
+            os << "!";
+
+        if( lazyExpr ) {
+            if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
+                os << "(" << *lazyExpr.m_transientExpression << ")";
+            else
+                os << *lazyExpr.m_transientExpression;
+        }
+        else {
+            os << "{** error - unchecked empty expression requested **}";
+        }
+        return os;
+    }
+
+    AssertionHandler::AssertionHandler
+        (   StringRef const& macroName,
+            SourceLineInfo const& lineInfo,
+            StringRef capturedExpression,
+            ResultDisposition::Flags resultDisposition )
+    :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
+        m_resultCapture( getResultCapture() )
+    {}
+
+    void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
+        m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
+    }
+    void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
+        m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
+    }
+
+    auto AssertionHandler::allowThrows() const -> bool {
+        return getCurrentContext().getConfig()->allowThrows();
+    }
+
+    void AssertionHandler::complete() {
+        setCompleted();
+        if( m_reaction.shouldDebugBreak ) {
+
+            // If you find your debugger stopping you here then go one level up on the
+            // call-stack for the code that caused it (typically a failed assertion)
+
+            // (To go back to the test and change execution, jump over the throw, next)
+            CATCH_BREAK_INTO_DEBUGGER();
+        }
+        if (m_reaction.shouldThrow) {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+            throw Catch::TestFailureException();
+#else
+            CATCH_ERROR( "Test failure requires aborting test!" );
+#endif
+        }
+    }
+    void AssertionHandler::setCompleted() {
+        m_completed = true;
+    }
+
+    void AssertionHandler::handleUnexpectedInflightException() {
+        m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
+    }
+
+    void AssertionHandler::handleExceptionThrownAsExpected() {
+        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
+    }
+    void AssertionHandler::handleExceptionNotThrownAsExpected() {
+        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
+    }
+
+    void AssertionHandler::handleUnexpectedExceptionNotThrown() {
+        m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
+    }
+
+    void AssertionHandler::handleThrowingCallSkipped() {
+        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
+    }
+
+    // This is the overload that takes a string and infers the Equals matcher from it
+    // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
+        handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
+    }
+
+} // namespace Catch
+// end catch_assertionhandler.cpp
+// start catch_assertionresult.cpp
+
+namespace Catch {
+    AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
+        lazyExpression(_lazyExpression),
+        resultType(_resultType) {}
+
+    std::string AssertionResultData::reconstructExpression() const {
+
+        if( reconstructedExpression.empty() ) {
+            if( lazyExpression ) {
+                ReusableStringStream rss;
+                rss << lazyExpression;
+                reconstructedExpression = rss.str();
+            }
+        }
+        return reconstructedExpression;
+    }
+
+    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+    :   m_info( info ),
+        m_resultData( data )
+    {}
+
+    // Result was a success
+    bool AssertionResult::succeeded() const {
+        return Catch::isOk( m_resultData.resultType );
+    }
+
+    // Result was a success, or failure is suppressed
+    bool AssertionResult::isOk() const {
+        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+    }
+
+    ResultWas::OfType AssertionResult::getResultType() const {
+        return m_resultData.resultType;
+    }
+
+    bool AssertionResult::hasExpression() const {
+        return !m_info.capturedExpression.empty();
+    }
+
+    bool AssertionResult::hasMessage() const {
+        return !m_resultData.message.empty();
+    }
+
+    std::string AssertionResult::getExpression() const {
+        // Possibly overallocating by 3 characters should be basically free
+        std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
+        if (isFalseTest(m_info.resultDisposition)) {
+            expr += "!(";
+        }
+        expr += m_info.capturedExpression;
+        if (isFalseTest(m_info.resultDisposition)) {
+            expr += ')';
+        }
+        return expr;
+    }
+
+    std::string AssertionResult::getExpressionInMacro() const {
+        std::string expr;
+        if( m_info.macroName.empty() )
+            expr = static_cast<std::string>(m_info.capturedExpression);
+        else {
+            expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
+            expr += m_info.macroName;
+            expr += "( ";
+            expr += m_info.capturedExpression;
+            expr += " )";
+        }
+        return expr;
+    }
+
+    bool AssertionResult::hasExpandedExpression() const {
+        return hasExpression() && getExpandedExpression() != getExpression();
+    }
+
+    std::string AssertionResult::getExpandedExpression() const {
+        std::string expr = m_resultData.reconstructExpression();
+        return expr.empty()
+                ? getExpression()
+                : expr;
+    }
+
+    std::string AssertionResult::getMessage() const {
+        return m_resultData.message;
+    }
+    SourceLineInfo AssertionResult::getSourceInfo() const {
+        return m_info.lineInfo;
+    }
+
+    StringRef AssertionResult::getTestMacroName() const {
+        return m_info.macroName;
+    }
+
+} // end namespace Catch
+// end catch_assertionresult.cpp
+// start catch_capture_matchers.cpp
+
+namespace Catch {
+
+    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
+
+    // This is the general overload that takes a any string matcher
+    // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
+    // the Equals matcher (so the header does not mention matchers)
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
+        std::string exceptionMessage = Catch::translateActiveException();
+        MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
+        handler.handleExpr( expr );
+    }
+
+} // namespace Catch
+// end catch_capture_matchers.cpp
+// start catch_commandline.cpp
+
+// start catch_commandline.h
+
+// start catch_clara.h
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#endif
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+#pragma clang diagnostic ignored "-Wshadow"
+#endif
+
+// start clara.hpp
+// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See https://github.com/philsquared/Clara for more details
+
+// Clara v1.1.5
+
+
+#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#ifndef CLARA_CONFIG_OPTIONAL_TYPE
+#ifdef __has_include
+#if __has_include(<optional>) && __cplusplus >= 201703L
+#include <optional>
+#define CLARA_CONFIG_OPTIONAL_TYPE std::optional
+#endif
+#endif
+#endif
+
+// ----------- #included from clara_textflow.hpp -----------
+
+// TextFlowCpp
+//
+// A single-header library for wrapping and laying out basic text, by Phil Nash
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This project is hosted at https://github.com/philsquared/textflowcpp
+
+
+#include <cassert>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+namespace clara {
+namespace TextFlow {
+
+inline auto isWhitespace(char c) -> bool {
+       static std::string chars = " \t\n\r";
+       return chars.find(c) != std::string::npos;
+}
+inline auto isBreakableBefore(char c) -> bool {
+       static std::string chars = "[({<|";
+       return chars.find(c) != std::string::npos;
+}
+inline auto isBreakableAfter(char c) -> bool {
+       static std::string chars = "])}>.,:;*+-=&/\\";
+       return chars.find(c) != std::string::npos;
+}
+
+class Columns;
+
+class Column {
+       std::vector<std::string> m_strings;
+       size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
+       size_t m_indent = 0;
+       size_t m_initialIndent = std::string::npos;
+
+public:
+       class iterator {
+               friend Column;
+
+               Column const& m_column;
+               size_t m_stringIndex = 0;
+               size_t m_pos = 0;
+
+               size_t m_len = 0;
+               size_t m_end = 0;
+               bool m_suffix = false;
+
+               iterator(Column const& column, size_t stringIndex)
+                       : m_column(column),
+                       m_stringIndex(stringIndex) {}
+
+               auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
+
+               auto isBoundary(size_t at) const -> bool {
+                       assert(at > 0);
+                       assert(at <= line().size());
+
+                       return at == line().size() ||
+                               (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
+                               isBreakableBefore(line()[at]) ||
+                               isBreakableAfter(line()[at - 1]);
+               }
+
+               void calcLength() {
+                       assert(m_stringIndex < m_column.m_strings.size());
+
+                       m_suffix = false;
+                       auto width = m_column.m_width - indent();
+                       m_end = m_pos;
+                       if (line()[m_pos] == '\n') {
+                               ++m_end;
+                       }
+                       while (m_end < line().size() && line()[m_end] != '\n')
+                               ++m_end;
+
+                       if (m_end < m_pos + width) {
+                               m_len = m_end - m_pos;
+                       } else {
+                               size_t len = width;
+                               while (len > 0 && !isBoundary(m_pos + len))
+                                       --len;
+                               while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
+                                       --len;
+
+                               if (len > 0) {
+                                       m_len = len;
+                               } else {
+                                       m_suffix = true;
+                                       m_len = width - 1;
+                               }
+                       }
+               }
+
+               auto indent() const -> size_t {
+                       auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
+                       return initial == std::string::npos ? m_column.m_indent : initial;
+               }
+
+               auto addIndentAndSuffix(std::string const &plain) const -> std::string {
+                       return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
+               }
+
+       public:
+               using difference_type = std::ptrdiff_t;
+               using value_type = std::string;
+               using pointer = value_type * ;
+               using reference = value_type & ;
+               using iterator_category = std::forward_iterator_tag;
+
+               explicit iterator(Column const& column) : m_column(column) {
+                       assert(m_column.m_width > m_column.m_indent);
+                       assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
+                       calcLength();
+                       if (m_len == 0)
+                               m_stringIndex++; // Empty string
+               }
+
+               auto operator *() const -> std::string {
+                       assert(m_stringIndex < m_column.m_strings.size());
+                       assert(m_pos <= m_end);
+                       return addIndentAndSuffix(line().substr(m_pos, m_len));
+               }
+
+               auto operator ++() -> iterator& {
+                       m_pos += m_len;
+                       if (m_pos < line().size() && line()[m_pos] == '\n')
+                               m_pos += 1;
+                       else
+                               while (m_pos < line().size() && isWhitespace(line()[m_pos]))
+                                       ++m_pos;
+
+                       if (m_pos == line().size()) {
+                               m_pos = 0;
+                               ++m_stringIndex;
+                       }
+                       if (m_stringIndex < m_column.m_strings.size())
+                               calcLength();
+                       return *this;
+               }
+               auto operator ++(int) -> iterator {
+                       iterator prev(*this);
+                       operator++();
+                       return prev;
+               }
+
+               auto operator ==(iterator const& other) const -> bool {
+                       return
+                               m_pos == other.m_pos &&
+                               m_stringIndex == other.m_stringIndex &&
+                               &m_column == &other.m_column;
+               }
+               auto operator !=(iterator const& other) const -> bool {
+                       return !operator==(other);
+               }
+       };
+       using const_iterator = iterator;
+
+       explicit Column(std::string const& text) { m_strings.push_back(text); }
+
+       auto width(size_t newWidth) -> Column& {
+               assert(newWidth > 0);
+               m_width = newWidth;
+               return *this;
+       }
+       auto indent(size_t newIndent) -> Column& {
+               m_indent = newIndent;
+               return *this;
+       }
+       auto initialIndent(size_t newIndent) -> Column& {
+               m_initialIndent = newIndent;
+               return *this;
+       }
+
+       auto width() const -> size_t { return m_width; }
+       auto begin() const -> iterator { return iterator(*this); }
+       auto end() const -> iterator { return { *this, m_strings.size() }; }
+
+       inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
+               bool first = true;
+               for (auto line : col) {
+                       if (first)
+                               first = false;
+                       else
+                               os << "\n";
+                       os << line;
+               }
+               return os;
+       }
+
+       auto operator + (Column const& other)->Columns;
+
+       auto toString() const -> std::string {
+               std::ostringstream oss;
+               oss << *this;
+               return oss.str();
+       }
+};
+
+class Spacer : public Column {
+
+public:
+       explicit Spacer(size_t spaceWidth) : Column("") {
+               width(spaceWidth);
+       }
+};
+
+class Columns {
+       std::vector<Column> m_columns;
+
+public:
+
+       class iterator {
+               friend Columns;
+               struct EndTag {};
+
+               std::vector<Column> const& m_columns;
+               std::vector<Column::iterator> m_iterators;
+               size_t m_activeIterators;
+
+               iterator(Columns const& columns, EndTag)
+                       : m_columns(columns.m_columns),
+                       m_activeIterators(0) {
+                       m_iterators.reserve(m_columns.size());
+
+                       for (auto const& col : m_columns)
+                               m_iterators.push_back(col.end());
+               }
+
+       public:
+               using difference_type = std::ptrdiff_t;
+               using value_type = std::string;
+               using pointer = value_type * ;
+               using reference = value_type & ;
+               using iterator_category = std::forward_iterator_tag;
+
+               explicit iterator(Columns const& columns)
+                       : m_columns(columns.m_columns),
+                       m_activeIterators(m_columns.size()) {
+                       m_iterators.reserve(m_columns.size());
+
+                       for (auto const& col : m_columns)
+                               m_iterators.push_back(col.begin());
+               }
+
+               auto operator ==(iterator const& other) const -> bool {
+                       return m_iterators == other.m_iterators;
+               }
+               auto operator !=(iterator const& other) const -> bool {
+                       return m_iterators != other.m_iterators;
+               }
+               auto operator *() const -> std::string {
+                       std::string row, padding;
+
+                       for (size_t i = 0; i < m_columns.size(); ++i) {
+                               auto width = m_columns[i].width();
+                               if (m_iterators[i] != m_columns[i].end()) {
+                                       std::string col = *m_iterators[i];
+                                       row += padding + col;
+                                       if (col.size() < width)
+                                               padding = std::string(width - col.size(), ' ');
+                                       else
+                                               padding = "";
+                               } else {
+                                       padding += std::string(width, ' ');
+                               }
+                       }
+                       return row;
+               }
+               auto operator ++() -> iterator& {
+                       for (size_t i = 0; i < m_columns.size(); ++i) {
+                               if (m_iterators[i] != m_columns[i].end())
+                                       ++m_iterators[i];
+                       }
+                       return *this;
+               }
+               auto operator ++(int) -> iterator {
+                       iterator prev(*this);
+                       operator++();
+                       return prev;
+               }
+       };
+       using const_iterator = iterator;
+
+       auto begin() const -> iterator { return iterator(*this); }
+       auto end() const -> iterator { return { *this, iterator::EndTag() }; }
+
+       auto operator += (Column const& col) -> Columns& {
+               m_columns.push_back(col);
+               return *this;
+       }
+       auto operator + (Column const& col) -> Columns {
+               Columns combined = *this;
+               combined += col;
+               return combined;
+       }
+
+       inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
+
+               bool first = true;
+               for (auto line : cols) {
+                       if (first)
+                               first = false;
+                       else
+                               os << "\n";
+                       os << line;
+               }
+               return os;
+       }
+
+       auto toString() const -> std::string {
+               std::ostringstream oss;
+               oss << *this;
+               return oss.str();
+       }
+};
+
+inline auto Column::operator + (Column const& other) -> Columns {
+       Columns cols;
+       cols += *this;
+       cols += other;
+       return cols;
+}
+}
+
+}
+}
+
+// ----------- end of #include from clara_textflow.hpp -----------
+// ........... back in clara.hpp
+
+#include <cctype>
+#include <string>
+#include <memory>
+#include <set>
+#include <algorithm>
+
+#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
+#define CATCH_PLATFORM_WINDOWS
+#endif
+
+namespace Catch { namespace clara {
+namespace detail {
+
+    // Traits for extracting arg and return type of lambdas (for single argument lambdas)
+    template<typename L>
+    struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
+
+    template<typename ClassT, typename ReturnT, typename... Args>
+    struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
+        static const bool isValid = false;
+    };
+
+    template<typename ClassT, typename ReturnT, typename ArgT>
+    struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
+        static const bool isValid = true;
+        using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
+        using ReturnType = ReturnT;
+    };
+
+    class TokenStream;
+
+    // Transport for raw args (copied from main args, or supplied via init list for testing)
+    class Args {
+        friend TokenStream;
+        std::string m_exeName;
+        std::vector<std::string> m_args;
+
+    public:
+        Args( int argc, char const* const* argv )
+            : m_exeName(argv[0]),
+              m_args(argv + 1, argv + argc) {}
+
+        Args( std::initializer_list<std::string> args )
+        :   m_exeName( *args.begin() ),
+            m_args( args.begin()+1, args.end() )
+        {}
+
+        auto exeName() const -> std::string {
+            return m_exeName;
+        }
+    };
+
+    // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
+    // may encode an option + its argument if the : or = form is used
+    enum class TokenType {
+        Option, Argument
+    };
+    struct Token {
+        TokenType type;
+        std::string token;
+    };
+
+    inline auto isOptPrefix( char c ) -> bool {
+        return c == '-'
+#ifdef CATCH_PLATFORM_WINDOWS
+            || c == '/'
+#endif
+        ;
+    }
+
+    // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
+    class TokenStream {
+        using Iterator = std::vector<std::string>::const_iterator;
+        Iterator it;
+        Iterator itEnd;
+        std::vector<Token> m_tokenBuffer;
+
+        void loadBuffer() {
+            m_tokenBuffer.resize( 0 );
+
+            // Skip any empty strings
+            while( it != itEnd && it->empty() )
+                ++it;
+
+            if( it != itEnd ) {
+                auto const &next = *it;
+                if( isOptPrefix( next[0] ) ) {
+                    auto delimiterPos = next.find_first_of( " :=" );
+                    if( delimiterPos != std::string::npos ) {
+                        m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
+                        m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
+                    } else {
+                        if( next[1] != '-' && next.size() > 2 ) {
+                            std::string opt = "- ";
+                            for( size_t i = 1; i < next.size(); ++i ) {
+                                opt[1] = next[i];
+                                m_tokenBuffer.push_back( { TokenType::Option, opt } );
+                            }
+                        } else {
+                            m_tokenBuffer.push_back( { TokenType::Option, next } );
+                        }
+                    }
+                } else {
+                    m_tokenBuffer.push_back( { TokenType::Argument, next } );
+                }
+            }
+        }
+
+    public:
+        explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
+
+        TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
+            loadBuffer();
+        }
+
+        explicit operator bool() const {
+            return !m_tokenBuffer.empty() || it != itEnd;
+        }
+
+        auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
+
+        auto operator*() const -> Token {
+            assert( !m_tokenBuffer.empty() );
+            return m_tokenBuffer.front();
+        }
+
+        auto operator->() const -> Token const * {
+            assert( !m_tokenBuffer.empty() );
+            return &m_tokenBuffer.front();
+        }
+
+        auto operator++() -> TokenStream & {
+            if( m_tokenBuffer.size() >= 2 ) {
+                m_tokenBuffer.erase( m_tokenBuffer.begin() );
+            } else {
+                if( it != itEnd )
+                    ++it;
+                loadBuffer();
+            }
+            return *this;
+        }
+    };
+
+    class ResultBase {
+    public:
+        enum Type {
+            Ok, LogicError, RuntimeError
+        };
+
+    protected:
+        ResultBase( Type type ) : m_type( type ) {}
+        virtual ~ResultBase() = default;
+
+        virtual void enforceOk() const = 0;
+
+        Type m_type;
+    };
+
+    template<typename T>
+    class ResultValueBase : public ResultBase {
+    public:
+        auto value() const -> T const & {
+            enforceOk();
+            return m_value;
+        }
+
+    protected:
+        ResultValueBase( Type type ) : ResultBase( type ) {}
+
+        ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
+            if( m_type == ResultBase::Ok )
+                new( &m_value ) T( other.m_value );
+        }
+
+        ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
+            new( &m_value ) T( value );
+        }
+
+        auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
+            if( m_type == ResultBase::Ok )
+                m_value.~T();
+            ResultBase::operator=(other);
+            if( m_type == ResultBase::Ok )
+                new( &m_value ) T( other.m_value );
+            return *this;
+        }
+
+        ~ResultValueBase() override {
+            if( m_type == Ok )
+                m_value.~T();
+        }
+
+        union {
+            T m_value;
+        };
+    };
+
+    template<>
+    class ResultValueBase<void> : public ResultBase {
+    protected:
+        using ResultBase::ResultBase;
+    };
+
+    template<typename T = void>
+    class BasicResult : public ResultValueBase<T> {
+    public:
+        template<typename U>
+        explicit BasicResult( BasicResult<U> const &other )
+        :   ResultValueBase<T>( other.type() ),
+            m_errorMessage( other.errorMessage() )
+        {
+            assert( type() != ResultBase::Ok );
+        }
+
+        template<typename U>
+        static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
+        static auto ok() -> BasicResult { return { ResultBase::Ok }; }
+        static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
+        static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
+
+        explicit operator bool() const { return m_type == ResultBase::Ok; }
+        auto type() const -> ResultBase::Type { return m_type; }
+        auto errorMessage() const -> std::string { return m_errorMessage; }
+
+    protected:
+        void enforceOk() const override {
+
+            // Errors shouldn't reach this point, but if they do
+            // the actual error message will be in m_errorMessage
+            assert( m_type != ResultBase::LogicError );
+            assert( m_type != ResultBase::RuntimeError );
+            if( m_type != ResultBase::Ok )
+                std::abort();
+        }
+
+        std::string m_errorMessage; // Only populated if resultType is an error
+
+        BasicResult( ResultBase::Type type, std::string const &message )
+        :   ResultValueBase<T>(type),
+            m_errorMessage(message)
+        {
+            assert( m_type != ResultBase::Ok );
+        }
+
+        using ResultValueBase<T>::ResultValueBase;
+        using ResultBase::m_type;
+    };
+
+    enum class ParseResultType {
+        Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
+    };
+
+    class ParseState {
+    public:
+
+        ParseState( ParseResultType type, TokenStream const &remainingTokens )
+        : m_type(type),
+          m_remainingTokens( remainingTokens )
+        {}
+
+        auto type() const -> ParseResultType { return m_type; }
+        auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
+
+    private:
+        ParseResultType m_type;
+        TokenStream m_remainingTokens;
+    };
+
+    using Result = BasicResult<void>;
+    using ParserResult = BasicResult<ParseResultType>;
+    using InternalParseResult = BasicResult<ParseState>;
+
+    struct HelpColumns {
+        std::string left;
+        std::string right;
+    };
+
+    template<typename T>
+    inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
+        std::stringstream ss;
+        ss << source;
+        ss >> target;
+        if( ss.fail() )
+            return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
+        else
+            return ParserResult::ok( ParseResultType::Matched );
+    }
+    inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
+        target = source;
+        return ParserResult::ok( ParseResultType::Matched );
+    }
+    inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
+        std::string srcLC = source;
+        std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
+        if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
+            target = true;
+        else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
+            target = false;
+        else
+            return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
+        return ParserResult::ok( ParseResultType::Matched );
+    }
+#ifdef CLARA_CONFIG_OPTIONAL_TYPE
+    template<typename T>
+    inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
+        T temp;
+        auto result = convertInto( source, temp );
+        if( result )
+            target = std::move(temp);
+        return result;
+    }
+#endif // CLARA_CONFIG_OPTIONAL_TYPE
+
+    struct NonCopyable {
+        NonCopyable() = default;
+        NonCopyable( NonCopyable const & ) = delete;
+        NonCopyable( NonCopyable && ) = delete;
+        NonCopyable &operator=( NonCopyable const & ) = delete;
+        NonCopyable &operator=( NonCopyable && ) = delete;
+    };
+
+    struct BoundRef : NonCopyable {
+        virtual ~BoundRef() = default;
+        virtual auto isContainer() const -> bool { return false; }
+        virtual auto isFlag() const -> bool { return false; }
+    };
+    struct BoundValueRefBase : BoundRef {
+        virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
+    };
+    struct BoundFlagRefBase : BoundRef {
+        virtual auto setFlag( bool flag ) -> ParserResult = 0;
+        virtual auto isFlag() const -> bool { return true; }
+    };
+
+    template<typename T>
+    struct BoundValueRef : BoundValueRefBase {
+        T &m_ref;
+
+        explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
+
+        auto setValue( std::string const &arg ) -> ParserResult override {
+            return convertInto( arg, m_ref );
+        }
+    };
+
+    template<typename T>
+    struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
+        std::vector<T> &m_ref;
+
+        explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
+
+        auto isContainer() const -> bool override { return true; }
+
+        auto setValue( std::string const &arg ) -> ParserResult override {
+            T temp;
+            auto result = convertInto( arg, temp );
+            if( result )
+                m_ref.push_back( temp );
+            return result;
+        }
+    };
+
+    struct BoundFlagRef : BoundFlagRefBase {
+        bool &m_ref;
+
+        explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
+
+        auto setFlag( bool flag ) -> ParserResult override {
+            m_ref = flag;
+            return ParserResult::ok( ParseResultType::Matched );
+        }
+    };
+
+    template<typename ReturnType>
+    struct LambdaInvoker {
+        static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
+
+        template<typename L, typename ArgType>
+        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
+            return lambda( arg );
+        }
+    };
+
+    template<>
+    struct LambdaInvoker<void> {
+        template<typename L, typename ArgType>
+        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
+            lambda( arg );
+            return ParserResult::ok( ParseResultType::Matched );
+        }
+    };
+
+    template<typename ArgType, typename L>
+    inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
+        ArgType temp{};
+        auto result = convertInto( arg, temp );
+        return !result
+           ? result
+           : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
+    }
+
+    template<typename L>
+    struct BoundLambda : BoundValueRefBase {
+        L m_lambda;
+
+        static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
+        explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
+
+        auto setValue( std::string const &arg ) -> ParserResult override {
+            return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
+        }
+    };
+
+    template<typename L>
+    struct BoundFlagLambda : BoundFlagRefBase {
+        L m_lambda;
+
+        static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
+        static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
+
+        explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
+
+        auto setFlag( bool flag ) -> ParserResult override {
+            return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
+        }
+    };
+
+    enum class Optionality { Optional, Required };
+
+    struct Parser;
+
+    class ParserBase {
+    public:
+        virtual ~ParserBase() = default;
+        virtual auto validate() const -> Result { return Result::ok(); }
+        virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;
+        virtual auto cardinality() const -> size_t { return 1; }
+
+        auto parse( Args const &args ) const -> InternalParseResult {
+            return parse( args.exeName(), TokenStream( args ) );
+        }
+    };
+
+    template<typename DerivedT>
+    class ComposableParserImpl : public ParserBase {
+    public:
+        template<typename T>
+        auto operator|( T const &other ) const -> Parser;
+
+               template<typename T>
+        auto operator+( T const &other ) const -> Parser;
+    };
+
+    // Common code and state for Args and Opts
+    template<typename DerivedT>
+    class ParserRefImpl : public ComposableParserImpl<DerivedT> {
+    protected:
+        Optionality m_optionality = Optionality::Optional;
+        std::shared_ptr<BoundRef> m_ref;
+        std::string m_hint;
+        std::string m_description;
+
+        explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
+
+    public:
+        template<typename T>
+        ParserRefImpl( T &ref, std::string const &hint )
+        :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
+            m_hint( hint )
+        {}
+
+        template<typename LambdaT>
+        ParserRefImpl( LambdaT const &ref, std::string const &hint )
+        :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
+            m_hint(hint)
+        {}
+
+        auto operator()( std::string const &description ) -> DerivedT & {
+            m_description = description;
+            return static_cast<DerivedT &>( *this );
+        }
+
+        auto optional() -> DerivedT & {
+            m_optionality = Optionality::Optional;
+            return static_cast<DerivedT &>( *this );
+        };
+
+        auto required() -> DerivedT & {
+            m_optionality = Optionality::Required;
+            return static_cast<DerivedT &>( *this );
+        };
+
+        auto isOptional() const -> bool {
+            return m_optionality == Optionality::Optional;
+        }
+
+        auto cardinality() const -> size_t override {
+            if( m_ref->isContainer() )
+                return 0;
+            else
+                return 1;
+        }
+
+        auto hint() const -> std::string { return m_hint; }
+    };
+
+    class ExeName : public ComposableParserImpl<ExeName> {
+        std::shared_ptr<std::string> m_name;
+        std::shared_ptr<BoundValueRefBase> m_ref;
+
+        template<typename LambdaT>
+        static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
+            return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
+        }
+
+    public:
+        ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
+
+        explicit ExeName( std::string &ref ) : ExeName() {
+            m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
+        }
+
+        template<typename LambdaT>
+        explicit ExeName( LambdaT const& lambda ) : ExeName() {
+            m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
+        }
+
+        // The exe name is not parsed out of the normal tokens, but is handled specially
+        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
+            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
+        }
+
+        auto name() const -> std::string { return *m_name; }
+        auto set( std::string const& newName ) -> ParserResult {
+
+            auto lastSlash = newName.find_last_of( "\\/" );
+            auto filename = ( lastSlash == std::string::npos )
+                    ? newName
+                    : newName.substr( lastSlash+1 );
+
+            *m_name = filename;
+            if( m_ref )
+                return m_ref->setValue( filename );
+            else
+                return ParserResult::ok( ParseResultType::Matched );
+        }
+    };
+
+    class Arg : public ParserRefImpl<Arg> {
+    public:
+        using ParserRefImpl::ParserRefImpl;
+
+        auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
+            auto validationResult = validate();
+            if( !validationResult )
+                return InternalParseResult( validationResult );
+
+            auto remainingTokens = tokens;
+            auto const &token = *remainingTokens;
+            if( token.type != TokenType::Argument )
+                return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
+
+            assert( !m_ref->isFlag() );
+            auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
+
+            auto result = valueRef->setValue( remainingTokens->token );
+            if( !result )
+                return InternalParseResult( result );
+            else
+                return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
+        }
+    };
+
+    inline auto normaliseOpt( std::string const &optName ) -> std::string {
+#ifdef CATCH_PLATFORM_WINDOWS
+        if( optName[0] == '/' )
+            return "-" + optName.substr( 1 );
+        else
+#endif
+            return optName;
+    }
+
+    class Opt : public ParserRefImpl<Opt> {
+    protected:
+        std::vector<std::string> m_optNames;
+
+    public:
+        template<typename LambdaT>
+        explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
+
+        explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
+
+        template<typename LambdaT>
+        Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
+
+        template<typename T>
+        Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
+
+        auto operator[]( std::string const &optName ) -> Opt & {
+            m_optNames.push_back( optName );
+            return *this;
+        }
+
+        auto getHelpColumns() const -> std::vector<HelpColumns> {
+            std::ostringstream oss;
+            bool first = true;
+            for( auto const &opt : m_optNames ) {
+                if (first)
+                    first = false;
+                else
+                    oss << ", ";
+                oss << opt;
+            }
+            if( !m_hint.empty() )
+                oss << " <" << m_hint << ">";
+            return { { oss.str(), m_description } };
+        }
+
+        auto isMatch( std::string const &optToken ) const -> bool {
+            auto normalisedToken = normaliseOpt( optToken );
+            for( auto const &name : m_optNames ) {
+                if( normaliseOpt( name ) == normalisedToken )
+                    return true;
+            }
+            return false;
+        }
+
+        using ParserBase::parse;
+
+        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
+            auto validationResult = validate();
+            if( !validationResult )
+                return InternalParseResult( validationResult );
+
+            auto remainingTokens = tokens;
+            if( remainingTokens && remainingTokens->type == TokenType::Option ) {
+                auto const &token = *remainingTokens;
+                if( isMatch(token.token ) ) {
+                    if( m_ref->isFlag() ) {
+                        auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
+                        auto result = flagRef->setFlag( true );
+                        if( !result )
+                            return InternalParseResult( result );
+                        if( result.value() == ParseResultType::ShortCircuitAll )
+                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
+                    } else {
+                        auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
+                        ++remainingTokens;
+                        if( !remainingTokens )
+                            return InternalParseResult::runtimeError( "Expected argument following " + token.token );
+                        auto const &argToken = *remainingTokens;
+                        if( argToken.type != TokenType::Argument )
+                            return InternalParseResult::runtimeError( "Expected argument following " + token.token );
+                        auto result = valueRef->setValue( argToken.token );
+                        if( !result )
+                            return InternalParseResult( result );
+                        if( result.value() == ParseResultType::ShortCircuitAll )
+                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
+                    }
+                    return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
+                }
+            }
+            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
+        }
+
+        auto validate() const -> Result override {
+            if( m_optNames.empty() )
+                return Result::logicError( "No options supplied to Opt" );
+            for( auto const &name : m_optNames ) {
+                if( name.empty() )
+                    return Result::logicError( "Option name cannot be empty" );
+#ifdef CATCH_PLATFORM_WINDOWS
+                if( name[0] != '-' && name[0] != '/' )
+                    return Result::logicError( "Option name must begin with '-' or '/'" );
+#else
+                if( name[0] != '-' )
+                    return Result::logicError( "Option name must begin with '-'" );
+#endif
+            }
+            return ParserRefImpl::validate();
+        }
+    };
+
+    struct Help : Opt {
+        Help( bool &showHelpFlag )
+        :   Opt([&]( bool flag ) {
+                showHelpFlag = flag;
+                return ParserResult::ok( ParseResultType::ShortCircuitAll );
+            })
+        {
+            static_cast<Opt &>( *this )
+                    ("display usage information")
+                    ["-?"]["-h"]["--help"]
+                    .optional();
+        }
+    };
+
+    struct Parser : ParserBase {
+
+        mutable ExeName m_exeName;
+        std::vector<Opt> m_options;
+        std::vector<Arg> m_args;
+
+        auto operator|=( ExeName const &exeName ) -> Parser & {
+            m_exeName = exeName;
+            return *this;
+        }
+
+        auto operator|=( Arg const &arg ) -> Parser & {
+            m_args.push_back(arg);
+            return *this;
+        }
+
+        auto operator|=( Opt const &opt ) -> Parser & {
+            m_options.push_back(opt);
+            return *this;
+        }
+
+        auto operator|=( Parser const &other ) -> Parser & {
+            m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
+            m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
+            return *this;
+        }
+
+        template<typename T>
+        auto operator|( T const &other ) const -> Parser {
+            return Parser( *this ) |= other;
+        }
+
+        // Forward deprecated interface with '+' instead of '|'
+        template<typename T>
+        auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
+        template<typename T>
+        auto operator+( T const &other ) const -> Parser { return operator|( other ); }
+
+        auto getHelpColumns() const -> std::vector<HelpColumns> {
+            std::vector<HelpColumns> cols;
+            for (auto const &o : m_options) {
+                auto childCols = o.getHelpColumns();
+                cols.insert( cols.end(), childCols.begin(), childCols.end() );
+            }
+            return cols;
+        }
+
+        void writeToStream( std::ostream &os ) const {
+            if (!m_exeName.name().empty()) {
+                os << "usage:\n" << "  " << m_exeName.name() << " ";
+                bool required = true, first = true;
+                for( auto const &arg : m_args ) {
+                    if (first)
+                        first = false;
+                    else
+                        os << " ";
+                    if( arg.isOptional() && required ) {
+                        os << "[";
+                        required = false;
+                    }
+                    os << "<" << arg.hint() << ">";
+                    if( arg.cardinality() == 0 )
+                        os << " ... ";
+                }
+                if( !required )
+                    os << "]";
+                if( !m_options.empty() )
+                    os << " options";
+                os << "\n\nwhere options are:" << std::endl;
+            }
+
+            auto rows = getHelpColumns();
+            size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
+            size_t optWidth = 0;
+            for( auto const &cols : rows )
+                optWidth = (std::max)(optWidth, cols.left.size() + 2);
+
+            optWidth = (std::min)(optWidth, consoleWidth/2);
+
+            for( auto const &cols : rows ) {
+                auto row =
+                        TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
+                        TextFlow::Spacer(4) +
+                        TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
+                os << row << std::endl;
+            }
+        }
+
+        friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
+            parser.writeToStream( os );
+            return os;
+        }
+
+        auto validate() const -> Result override {
+            for( auto const &opt : m_options ) {
+                auto result = opt.validate();
+                if( !result )
+                    return result;
+            }
+            for( auto const &arg : m_args ) {
+                auto result = arg.validate();
+                if( !result )
+                    return result;
+            }
+            return Result::ok();
+        }
+
+        using ParserBase::parse;
+
+        auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
+
+            struct ParserInfo {
+                ParserBase const* parser = nullptr;
+                size_t count = 0;
+            };
+            const size_t totalParsers = m_options.size() + m_args.size();
+            assert( totalParsers < 512 );
+            // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
+            ParserInfo parseInfos[512];
+
+            {
+                size_t i = 0;
+                for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
+                for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
+            }
+
+            m_exeName.set( exeName );
+
+            auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
+            while( result.value().remainingTokens() ) {
+                bool tokenParsed = false;
+
+                for( size_t i = 0; i < totalParsers; ++i ) {
+                    auto&  parseInfo = parseInfos[i];
+                    if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
+                        result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
+                        if (!result)
+                            return result;
+                        if (result.value().type() != ParseResultType::NoMatch) {
+                            tokenParsed = true;
+                            ++parseInfo.count;
+                            break;
+                        }
+                    }
+                }
+
+                if( result.value().type() == ParseResultType::ShortCircuitAll )
+                    return result;
+                if( !tokenParsed )
+                    return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
+            }
+            // !TBD Check missing required options
+            return result;
+        }
+    };
+
+    template<typename DerivedT>
+    template<typename T>
+    auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
+        return Parser() | static_cast<DerivedT const &>( *this ) | other;
+    }
+} // namespace detail
+
+// A Combined parser
+using detail::Parser;
+
+// A parser for options
+using detail::Opt;
+
+// A parser for arguments
+using detail::Arg;
+
+// Wrapper for argc, argv from main()
+using detail::Args;
+
+// Specifies the name of the executable
+using detail::ExeName;
+
+// Convenience wrapper for option parser that specifies the help option
+using detail::Help;
+
+// enum of result types from a parse
+using detail::ParseResultType;
+
+// Result type for parser operation
+using detail::ParserResult;
+
+}} // namespace Catch::clara
+
+// end clara.hpp
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+// end catch_clara.h
+namespace Catch {
+
+    clara::Parser makeCommandLineParser( ConfigData& config );
+
+} // end namespace Catch
+
+// end catch_commandline.h
+#include <fstream>
+#include <ctime>
+
+namespace Catch {
+
+    clara::Parser makeCommandLineParser( ConfigData& config ) {
+
+        using namespace clara;
+
+        auto const setWarning = [&]( std::string const& warning ) {
+                auto warningSet = [&]() {
+                    if( warning == "NoAssertions" )
+                        return WarnAbout::NoAssertions;
+
+                    if ( warning == "NoTests" )
+                        return WarnAbout::NoTests;
+
+                    return WarnAbout::Nothing;
+                }();
+
+                if (warningSet == WarnAbout::Nothing)
+                    return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
+                config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
+                return ParserResult::ok( ParseResultType::Matched );
+            };
+        auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
+                std::ifstream f( filename.c_str() );
+                if( !f.is_open() )
+                    return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
+
+                std::string line;
+                while( std::getline( f, line ) ) {
+                    line = trim(line);
+                    if( !line.empty() && !startsWith( line, '#' ) ) {
+                        if( !startsWith( line, '"' ) )
+                            line = '"' + line + '"';
+                        config.testsOrTags.push_back( line );
+                        config.testsOrTags.emplace_back( "," );
+                    }
+                }
+                //Remove comma in the end
+                if(!config.testsOrTags.empty())
+                    config.testsOrTags.erase( config.testsOrTags.end()-1 );
+
+                return ParserResult::ok( ParseResultType::Matched );
+            };
+        auto const setTestOrder = [&]( std::string const& order ) {
+                if( startsWith( "declared", order ) )
+                    config.runOrder = RunTests::InDeclarationOrder;
+                else if( startsWith( "lexical", order ) )
+                    config.runOrder = RunTests::InLexicographicalOrder;
+                else if( startsWith( "random", order ) )
+                    config.runOrder = RunTests::InRandomOrder;
+                else
+                    return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
+                return ParserResult::ok( ParseResultType::Matched );
+            };
+        auto const setRngSeed = [&]( std::string const& seed ) {
+                if( seed != "time" )
+                    return clara::detail::convertInto( seed, config.rngSeed );
+                config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
+                return ParserResult::ok( ParseResultType::Matched );
+            };
+        auto const setColourUsage = [&]( std::string const& useColour ) {
+                    auto mode = toLower( useColour );
+
+                    if( mode == "yes" )
+                        config.useColour = UseColour::Yes;
+                    else if( mode == "no" )
+                        config.useColour = UseColour::No;
+                    else if( mode == "auto" )
+                        config.useColour = UseColour::Auto;
+                    else
+                        return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
+                return ParserResult::ok( ParseResultType::Matched );
+            };
+        auto const setWaitForKeypress = [&]( std::string const& keypress ) {
+                auto keypressLc = toLower( keypress );
+                if (keypressLc == "never")
+                    config.waitForKeypress = WaitForKeypress::Never;
+                else if( keypressLc == "start" )
+                    config.waitForKeypress = WaitForKeypress::BeforeStart;
+                else if( keypressLc == "exit" )
+                    config.waitForKeypress = WaitForKeypress::BeforeExit;
+                else if( keypressLc == "both" )
+                    config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
+                else
+                    return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
+            return ParserResult::ok( ParseResultType::Matched );
+            };
+        auto const setVerbosity = [&]( std::string const& verbosity ) {
+            auto lcVerbosity = toLower( verbosity );
+            if( lcVerbosity == "quiet" )
+                config.verbosity = Verbosity::Quiet;
+            else if( lcVerbosity == "normal" )
+                config.verbosity = Verbosity::Normal;
+            else if( lcVerbosity == "high" )
+                config.verbosity = Verbosity::High;
+            else
+                return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
+            return ParserResult::ok( ParseResultType::Matched );
+        };
+        auto const setReporter = [&]( std::string const& reporter ) {
+            IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+
+            auto lcReporter = toLower( reporter );
+            auto result = factories.find( lcReporter );
+
+            if( factories.end() != result )
+                config.reporterName = lcReporter;
+            else
+                return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
+            return ParserResult::ok( ParseResultType::Matched );
+        };
+
+        auto cli
+            = ExeName( config.processName )
+            | Help( config.showHelp )
+            | Opt( config.listTests )
+                ["-l"]["--list-tests"]
+                ( "list all/matching test cases" )
+            | Opt( config.listTags )
+                ["-t"]["--list-tags"]
+                ( "list all/matching tags" )
+            | Opt( config.showSuccessfulTests )
+                ["-s"]["--success"]
+                ( "include successful tests in output" )
+            | Opt( config.shouldDebugBreak )
+                ["-b"]["--break"]
+                ( "break into debugger on failure" )
+            | Opt( config.noThrow )
+                ["-e"]["--nothrow"]
+                ( "skip exception tests" )
+            | Opt( config.showInvisibles )
+                ["-i"]["--invisibles"]
+                ( "show invisibles (tabs, newlines)" )
+            | Opt( config.outputFilename, "filename" )
+                ["-o"]["--out"]
+                ( "output filename" )
+            | Opt( setReporter, "name" )
+                ["-r"]["--reporter"]
+                ( "reporter to use (defaults to console)" )
+            | Opt( config.name, "name" )
+                ["-n"]["--name"]
+                ( "suite name" )
+            | Opt( [&]( bool ){ config.abortAfter = 1; } )
+                ["-a"]["--abort"]
+                ( "abort at first failure" )
+            | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
+                ["-x"]["--abortx"]
+                ( "abort after x failures" )
+            | Opt( setWarning, "warning name" )
+                ["-w"]["--warn"]
+                ( "enable warnings" )
+            | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
+                ["-d"]["--durations"]
+                ( "show test durations" )
+            | Opt( config.minDuration, "seconds" )
+                ["-D"]["--min-duration"]
+                ( "show test durations for tests taking at least the given number of seconds" )
+            | Opt( loadTestNamesFromFile, "filename" )
+                ["-f"]["--input-file"]
+                ( "load test names to run from a file" )
+            | Opt( config.filenamesAsTags )
+                ["-#"]["--filenames-as-tags"]
+                ( "adds a tag for the filename" )
+            | Opt( config.sectionsToRun, "section name" )
+                ["-c"]["--section"]
+                ( "specify section to run" )
+            | Opt( setVerbosity, "quiet|normal|high" )
+                ["-v"]["--verbosity"]
+                ( "set output verbosity" )
+            | Opt( config.listTestNamesOnly )
+                ["--list-test-names-only"]
+                ( "list all/matching test cases names only" )
+            | Opt( config.listReporters )
+                ["--list-reporters"]
+                ( "list all reporters" )
+            | Opt( setTestOrder, "decl|lex|rand" )
+                ["--order"]
+                ( "test case order (defaults to decl)" )
+            | Opt( setRngSeed, "'time'|number" )
+                ["--rng-seed"]
+                ( "set a specific seed for random numbers" )
+            | Opt( setColourUsage, "yes|no" )
+                ["--use-colour"]
+                ( "should output be colourised" )
+            | Opt( config.libIdentify )
+                ["--libidentify"]
+                ( "report name and version according to libidentify standard" )
+            | Opt( setWaitForKeypress, "never|start|exit|both" )
+                ["--wait-for-keypress"]
+                ( "waits for a keypress before exiting" )
+            | Opt( config.benchmarkSamples, "samples" )
+                ["--benchmark-samples"]
+                ( "number of samples to collect (default: 100)" )
+            | Opt( config.benchmarkResamples, "resamples" )
+                ["--benchmark-resamples"]
+                ( "number of resamples for the bootstrap (default: 100000)" )
+            | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
+                ["--benchmark-confidence-interval"]
+                ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
+            | Opt( config.benchmarkNoAnalysis )
+                ["--benchmark-no-analysis"]
+                ( "perform only measurements; do not perform any analysis" )
+            | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
+                ["--benchmark-warmup-time"]
+                ( "amount of time in milliseconds spent on warming up each test (default: 100)" )
+            | Arg( config.testsOrTags, "test name|pattern|tags" )
+                ( "which test or tests to use" );
+
+        return cli;
+    }
+
+} // end namespace Catch
+// end catch_commandline.cpp
+// start catch_common.cpp
+
+#include <cstring>
+#include <ostream>
+
+namespace Catch {
+
+    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
+        return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
+    }
+    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
+        // We can assume that the same file will usually have the same pointer.
+        // Thus, if the pointers are the same, there is no point in calling the strcmp
+        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
+    }
+
+    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+        os << info.file << '(' << info.line << ')';
+#else
+        os << info.file << ':' << info.line;
+#endif
+        return os;
+    }
+
+    std::string StreamEndStop::operator+() const {
+        return std::string();
+    }
+
+    NonCopyable::NonCopyable() = default;
+    NonCopyable::~NonCopyable() = default;
+
+}
+// end catch_common.cpp
+// start catch_config.cpp
+
+namespace Catch {
+
+    Config::Config( ConfigData const& data )
+    :   m_data( data ),
+        m_stream( openStream() )
+    {
+        // We need to trim filter specs to avoid trouble with superfluous
+        // whitespace (esp. important for bdd macros, as those are manually
+        // aligned with whitespace).
+
+        for (auto& elem : m_data.testsOrTags) {
+            elem = trim(elem);
+        }
+        for (auto& elem : m_data.sectionsToRun) {
+            elem = trim(elem);
+        }
+
+        TestSpecParser parser(ITagAliasRegistry::get());
+        if (!m_data.testsOrTags.empty()) {
+            m_hasTestFilters = true;
+            for (auto const& testOrTags : m_data.testsOrTags) {
+                parser.parse(testOrTags);
+            }
+        }
+        m_testSpec = parser.testSpec();
+    }
+
+    std::string const& Config::getFilename() const {
+        return m_data.outputFilename ;
+    }
+
+    bool Config::listTests() const          { return m_data.listTests; }
+    bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }
+    bool Config::listTags() const           { return m_data.listTags; }
+    bool Config::listReporters() const      { return m_data.listReporters; }
+
+    std::string Config::getProcessName() const { return m_data.processName; }
+    std::string const& Config::getReporterName() const { return m_data.reporterName; }
+
+    std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
+    std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
+
+    TestSpec const& Config::testSpec() const { return m_testSpec; }
+    bool Config::hasTestFilters() const { return m_hasTestFilters; }
+
+    bool Config::showHelp() const { return m_data.showHelp; }
+
+    // IConfig interface
+    bool Config::allowThrows() const                   { return !m_data.noThrow; }
+    std::ostream& Config::stream() const               { return m_stream->stream(); }
+    std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }
+    bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }
+    bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }
+    bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }
+    ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
+    double Config::minDuration() const                 { return m_data.minDuration; }
+    RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
+    unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
+    UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
+    bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
+    int Config::abortAfter() const                     { return m_data.abortAfter; }
+    bool Config::showInvisibles() const                { return m_data.showInvisibles; }
+    Verbosity Config::verbosity() const                { return m_data.verbosity; }
+
+    bool Config::benchmarkNoAnalysis() const                      { return m_data.benchmarkNoAnalysis; }
+    int Config::benchmarkSamples() const                          { return m_data.benchmarkSamples; }
+    double Config::benchmarkConfidenceInterval() const            { return m_data.benchmarkConfidenceInterval; }
+    unsigned int Config::benchmarkResamples() const               { return m_data.benchmarkResamples; }
+    std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
+
+    IStream const* Config::openStream() {
+        return Catch::makeStream(m_data.outputFilename);
+    }
+
+} // end namespace Catch
+// end catch_config.cpp
+// start catch_console_colour.cpp
+
+#if defined(__clang__)
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+// start catch_errno_guard.h
+
+namespace Catch {
+
+    class ErrnoGuard {
+    public:
+        ErrnoGuard();
+        ~ErrnoGuard();
+    private:
+        int m_oldErrno;
+    };
+
+}
+
+// end catch_errno_guard.h
+// start catch_windows_h_proxy.h
+
+
+#if defined(CATCH_PLATFORM_WINDOWS)
+
+#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
+#  define CATCH_DEFINED_NOMINMAX
+#  define NOMINMAX
+#endif
+#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
+#  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+#ifdef CATCH_DEFINED_NOMINMAX
+#  undef NOMINMAX
+#endif
+#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
+#  undef WIN32_LEAN_AND_MEAN
+#endif
+
+#endif // defined(CATCH_PLATFORM_WINDOWS)
+
+// end catch_windows_h_proxy.h
+#include <sstream>
+
+namespace Catch {
+    namespace {
+
+        struct IColourImpl {
+            virtual ~IColourImpl() = default;
+            virtual void use( Colour::Code _colourCode ) = 0;
+        };
+
+        struct NoColourImpl : IColourImpl {
+            void use( Colour::Code ) override {}
+
+            static IColourImpl* instance() {
+                static NoColourImpl s_instance;
+                return &s_instance;
+            }
+        };
+
+    } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+#   ifdef CATCH_PLATFORM_WINDOWS
+#       define CATCH_CONFIG_COLOUR_WINDOWS
+#   else
+#       define CATCH_CONFIG_COLOUR_ANSI
+#   endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+namespace {
+
+    class Win32ColourImpl : public IColourImpl {
+    public:
+        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+        {
+            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
+            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
+        }
+
+        void use( Colour::Code _colourCode ) override {
+            switch( _colourCode ) {
+                case Colour::None:      return setTextAttribute( originalForegroundAttributes );
+                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
+                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
+                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
+                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+                case Colour::Grey:      return setTextAttribute( 0 );
+
+                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
+                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+                case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
+
+                case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
+
+                default:
+                    CATCH_ERROR( "Unknown colour requested" );
+            }
+        }
+
+    private:
+        void setTextAttribute( WORD _textAttribute ) {
+            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
+        }
+        HANDLE stdoutHandle;
+        WORD originalForegroundAttributes;
+        WORD originalBackgroundAttributes;
+    };
+
+    IColourImpl* platformColourInstance() {
+        static Win32ColourImpl s_instance;
+
+        IConfigPtr config = getCurrentContext().getConfig();
+        UseColour::YesOrNo colourMode = config
+            ? config->useColour()
+            : UseColour::Auto;
+        if( colourMode == UseColour::Auto )
+            colourMode = UseColour::Yes;
+        return colourMode == UseColour::Yes
+            ? &s_instance
+            : NoColourImpl::instance();
+    }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+    // use POSIX/ ANSI console terminal codes
+    // Thanks to Adam Strzelecki for original contribution
+    // (http://github.com/nanoant)
+    // https://github.com/philsquared/Catch/pull/131
+    class PosixColourImpl : public IColourImpl {
+    public:
+        void use( Colour::Code _colourCode ) override {
+            switch( _colourCode ) {
+                case Colour::None:
+                case Colour::White:     return setColour( "[0m" );
+                case Colour::Red:       return setColour( "[0;31m" );
+                case Colour::Green:     return setColour( "[0;32m" );
+                case Colour::Blue:      return setColour( "[0;34m" );
+                case Colour::Cyan:      return setColour( "[0;36m" );
+                case Colour::Yellow:    return setColour( "[0;33m" );
+                case Colour::Grey:      return setColour( "[1;30m" );
+
+                case Colour::LightGrey:     return setColour( "[0;37m" );
+                case Colour::BrightRed:     return setColour( "[1;31m" );
+                case Colour::BrightGreen:   return setColour( "[1;32m" );
+                case Colour::BrightWhite:   return setColour( "[1;37m" );
+                case Colour::BrightYellow:  return setColour( "[1;33m" );
+
+                case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
+                default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
+            }
+        }
+        static IColourImpl* instance() {
+            static PosixColourImpl s_instance;
+            return &s_instance;
+        }
+
+    private:
+        void setColour( const char* _escapeCode ) {
+            getCurrentContext().getConfig()->stream()
+                << '\033' << _escapeCode;
+        }
+    };
+
+    bool useColourOnPlatform() {
+        return
+#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
+            !isDebuggerActive() &&
+#endif
+#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
+            isatty(STDOUT_FILENO)
+#else
+            false
+#endif
+            ;
+    }
+    IColourImpl* platformColourInstance() {
+        ErrnoGuard guard;
+        IConfigPtr config = getCurrentContext().getConfig();
+        UseColour::YesOrNo colourMode = config
+            ? config->useColour()
+            : UseColour::Auto;
+        if( colourMode == UseColour::Auto )
+            colourMode = useColourOnPlatform()
+                ? UseColour::Yes
+                : UseColour::No;
+        return colourMode == UseColour::Yes
+            ? PosixColourImpl::instance()
+            : NoColourImpl::instance();
+    }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else  // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+    Colour::Colour( Code _colourCode ) { use( _colourCode ); }
+    Colour::Colour( Colour&& other ) noexcept {
+        m_moved = other.m_moved;
+        other.m_moved = true;
+    }
+    Colour& Colour::operator=( Colour&& other ) noexcept {
+        m_moved = other.m_moved;
+        other.m_moved  = true;
+        return *this;
+    }
+
+    Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+    void Colour::use( Code _colourCode ) {
+        static IColourImpl* impl = platformColourInstance();
+        // Strictly speaking, this cannot possibly happen.
+        // However, under some conditions it does happen (see #1626),
+        // and this change is small enough that we can let practicality
+        // triumph over purity in this case.
+        if (impl != nullptr) {
+            impl->use( _colourCode );
+        }
+    }
+
+    std::ostream& operator << ( std::ostream& os, Colour const& ) {
+        return os;
+    }
+
+} // end namespace Catch
+
+#if defined(__clang__)
+#    pragma clang diagnostic pop
+#endif
+
+// end catch_console_colour.cpp
+// start catch_context.cpp
+
+namespace Catch {
+
+    class Context : public IMutableContext, NonCopyable {
+
+    public: // IContext
+        IResultCapture* getResultCapture() override {
+            return m_resultCapture;
+        }
+        IRunner* getRunner() override {
+            return m_runner;
+        }
+
+        IConfigPtr const& getConfig() const override {
+            return m_config;
+        }
+
+        ~Context() override;
+
+    public: // IMutableContext
+        void setResultCapture( IResultCapture* resultCapture ) override {
+            m_resultCapture = resultCapture;
+        }
+        void setRunner( IRunner* runner ) override {
+            m_runner = runner;
+        }
+        void setConfig( IConfigPtr const& config ) override {
+            m_config = config;
+        }
+
+        friend IMutableContext& getCurrentMutableContext();
+
+    private:
+        IConfigPtr m_config;
+        IRunner* m_runner = nullptr;
+        IResultCapture* m_resultCapture = nullptr;
+    };
+
+    IMutableContext *IMutableContext::currentContext = nullptr;
+
+    void IMutableContext::createContext()
+    {
+        currentContext = new Context();
+    }
+
+    void cleanUpContext() {
+        delete IMutableContext::currentContext;
+        IMutableContext::currentContext = nullptr;
+    }
+    IContext::~IContext() = default;
+    IMutableContext::~IMutableContext() = default;
+    Context::~Context() = default;
+
+    SimplePcg32& rng() {
+        static SimplePcg32 s_rng;
+        return s_rng;
+    }
+
+}
+// end catch_context.cpp
+// start catch_debug_console.cpp
+
+// start catch_debug_console.h
+
+#include <string>
+
+namespace Catch {
+    void writeToDebugConsole( std::string const& text );
+}
+
+// end catch_debug_console.h
+#if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+#include <android/log.h>
+
+    namespace Catch {
+        void writeToDebugConsole( std::string const& text ) {
+            __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
+        }
+    }
+
+#elif defined(CATCH_PLATFORM_WINDOWS)
+
+    namespace Catch {
+        void writeToDebugConsole( std::string const& text ) {
+            ::OutputDebugStringA( text.c_str() );
+        }
+    }
+
+#else
+
+    namespace Catch {
+        void writeToDebugConsole( std::string const& text ) {
+            // !TBD: Need a version for Mac/ XCode and other IDEs
+            Catch::cout() << text;
+        }
+    }
+
+#endif // Platform
+// end catch_debug_console.cpp
+// start catch_debugger.cpp
+
+#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
+
+#  include <cassert>
+#  include <sys/types.h>
+#  include <unistd.h>
+#  include <cstddef>
+#  include <ostream>
+
+#ifdef __apple_build_version__
+    // These headers will only compile with AppleClang (XCode)
+    // For other compilers (Clang, GCC, ... ) we need to exclude them
+#  include <sys/sysctl.h>
+#endif
+
+    namespace Catch {
+        #ifdef __apple_build_version__
+        // The following function is taken directly from the following technical note:
+        // https://developer.apple.com/library/archive/qa/qa1361/_index.html
+
+        // Returns true if the current process is being debugged (either
+        // running under the debugger or has a debugger attached post facto).
+        bool isDebuggerActive(){
+            int                 mib[4];
+            struct kinfo_proc   info;
+            std::size_t         size;
+
+            // Initialize the flags so that, if sysctl fails for some bizarre
+            // reason, we get a predictable result.
+
+            info.kp_proc.p_flag = 0;
+
+            // Initialize mib, which tells sysctl the info we want, in this case
+            // we're looking for information about a specific process ID.
+
+            mib[0] = CTL_KERN;
+            mib[1] = KERN_PROC;
+            mib[2] = KERN_PROC_PID;
+            mib[3] = getpid();
+
+            // Call sysctl.
+
+            size = sizeof(info);
+            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
+                Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+                return false;
+            }
+
+            // We're being debugged if the P_TRACED flag is set.
+
+            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+        }
+        #else
+        bool isDebuggerActive() {
+            // We need to find another way to determine this for non-appleclang compilers on macOS
+            return false;
+        }
+        #endif
+    } // namespace Catch
+
+#elif defined(CATCH_PLATFORM_LINUX)
+    #include <fstream>
+    #include <string>
+
+    namespace Catch{
+        // The standard POSIX way of detecting a debugger is to attempt to
+        // ptrace() the process, but this needs to be done from a child and not
+        // this process itself to still allow attaching to this process later
+        // if wanted, so is rather heavy. Under Linux we have the PID of the
+        // "debugger" (which doesn't need to be gdb, of course, it could also
+        // be strace, for example) in /proc/$PID/status, so just get it from
+        // there instead.
+        bool isDebuggerActive(){
+            // Libstdc++ has a bug, where std::ifstream sets errno to 0
+            // This way our users can properly assert over errno values
+            ErrnoGuard guard;
+            std::ifstream in("/proc/self/status");
+            for( std::string line; std::getline(in, line); ) {
+                static const int PREFIX_LEN = 11;
+                if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
+                    // We're traced if the PID is not 0 and no other PID starts
+                    // with 0 digit, so it's enough to check for just a single
+                    // character.
+                    return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
+                }
+            }
+
+            return false;
+        }
+    } // namespace Catch
+#elif defined(_MSC_VER)
+    extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+    namespace Catch {
+        bool isDebuggerActive() {
+            return IsDebuggerPresent() != 0;
+        }
+    }
+#elif defined(__MINGW32__)
+    extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+    namespace Catch {
+        bool isDebuggerActive() {
+            return IsDebuggerPresent() != 0;
+        }
+    }
+#else
+    namespace Catch {
+       bool isDebuggerActive() { return false; }
+    }
+#endif // Platform
+// end catch_debugger.cpp
+// start catch_decomposer.cpp
+
+namespace Catch {
+
+    ITransientExpression::~ITransientExpression() = default;
+
+    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
+        if( lhs.size() + rhs.size() < 40 &&
+                lhs.find('\n') == std::string::npos &&
+                rhs.find('\n') == std::string::npos )
+            os << lhs << " " << op << " " << rhs;
+        else
+            os << lhs << "\n" << op << "\n" << rhs;
+    }
+}
+// end catch_decomposer.cpp
+// start catch_enforce.cpp
+
+#include <stdexcept>
+
+namespace Catch {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
+    [[noreturn]]
+    void throw_exception(std::exception const& e) {
+        Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
+                      << "The message was: " << e.what() << '\n';
+        std::terminate();
+    }
+#endif
+
+    [[noreturn]]
+    void throw_logic_error(std::string const& msg) {
+        throw_exception(std::logic_error(msg));
+    }
+
+    [[noreturn]]
+    void throw_domain_error(std::string const& msg) {
+        throw_exception(std::domain_error(msg));
+    }
+
+    [[noreturn]]
+    void throw_runtime_error(std::string const& msg) {
+        throw_exception(std::runtime_error(msg));
+    }
+
+} // namespace Catch;
+// end catch_enforce.cpp
+// start catch_enum_values_registry.cpp
+// start catch_enum_values_registry.h
+
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+    namespace Detail {
+
+        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
+
+        class EnumValuesRegistry : public IMutableEnumValuesRegistry {
+
+            std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
+
+            EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
+        };
+
+        std::vector<StringRef> parseEnums( StringRef enums );
+
+    } // Detail
+
+} // Catch
+
+// end catch_enum_values_registry.h
+
+#include <map>
+#include <cassert>
+
+namespace Catch {
+
+    IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
+
+    namespace Detail {
+
+        namespace {
+            // Extracts the actual name part of an enum instance
+            // In other words, it returns the Blue part of Bikeshed::Colour::Blue
+            StringRef extractInstanceName(StringRef enumInstance) {
+                // Find last occurrence of ":"
+                size_t name_start = enumInstance.size();
+                while (name_start > 0 && enumInstance[name_start - 1] != ':') {
+                    --name_start;
+                }
+                return enumInstance.substr(name_start, enumInstance.size() - name_start);
+            }
+        }
+
+        std::vector<StringRef> parseEnums( StringRef enums ) {
+            auto enumValues = splitStringRef( enums, ',' );
+            std::vector<StringRef> parsed;
+            parsed.reserve( enumValues.size() );
+            for( auto const& enumValue : enumValues ) {
+                parsed.push_back(trim(extractInstanceName(enumValue)));
+            }
+            return parsed;
+        }
+
+        EnumInfo::~EnumInfo() {}
+
+        StringRef EnumInfo::lookup( int value ) const {
+            for( auto const& valueToName : m_values ) {
+                if( valueToName.first == value )
+                    return valueToName.second;
+            }
+            return "{** unexpected enum value **}"_sr;
+        }
+
+        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
+            std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
+            enumInfo->m_name = enumName;
+            enumInfo->m_values.reserve( values.size() );
+
+            const auto valueNames = Catch::Detail::parseEnums( allValueNames );
+            assert( valueNames.size() == values.size() );
+            std::size_t i = 0;
+            for( auto value : values )
+                enumInfo->m_values.emplace_back(value, valueNames[i++]);
+
+            return enumInfo;
+        }
+
+        EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
+            m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
+            return *m_enumInfos.back();
+        }
+
+    } // Detail
+} // Catch
+
+// end catch_enum_values_registry.cpp
+// start catch_errno_guard.cpp
+
+#include <cerrno>
+
+namespace Catch {
+        ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
+        ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
+}
+// end catch_errno_guard.cpp
+// start catch_exception_translator_registry.cpp
+
+// start catch_exception_translator_registry.h
+
+#include <vector>
+#include <string>
+#include <memory>
+
+namespace Catch {
+
+    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+    public:
+        ~ExceptionTranslatorRegistry();
+        virtual void registerTranslator( const IExceptionTranslator* translator );
+        std::string translateActiveException() const override;
+        std::string tryTranslators() const;
+
+    private:
+        std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
+    };
+}
+
+// end catch_exception_translator_registry.h
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+    ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
+    }
+
+    void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
+        m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
+    }
+
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+    std::string ExceptionTranslatorRegistry::translateActiveException() const {
+        try {
+#ifdef __OBJC__
+            // In Objective-C try objective-c exceptions first
+            @try {
+                return tryTranslators();
+            }
+            @catch (NSException *exception) {
+                return Catch::Detail::stringify( [exception description] );
+            }
+#else
+            // Compiling a mixed mode project with MSVC means that CLR
+            // exceptions will be caught in (...) as well. However, these
+            // do not fill-in std::current_exception and thus lead to crash
+            // when attempting rethrow.
+            // /EHa switch also causes structured exceptions to be caught
+            // here, but they fill-in current_exception properly, so
+            // at worst the output should be a little weird, instead of
+            // causing a crash.
+            if (std::current_exception() == nullptr) {
+                return "Non C++ exception. Possibly a CLR exception.";
+            }
+            return tryTranslators();
+#endif
+        }
+        catch( TestFailureException& ) {
+            std::rethrow_exception(std::current_exception());
+        }
+        catch( std::exception& ex ) {
+            return ex.what();
+        }
+        catch( std::string& msg ) {
+            return msg;
+        }
+        catch( const char* msg ) {
+            return msg;
+        }
+        catch(...) {
+            return "Unknown exception";
+        }
+    }
+
+    std::string ExceptionTranslatorRegistry::tryTranslators() const {
+        if (m_translators.empty()) {
+            std::rethrow_exception(std::current_exception());
+        } else {
+            return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
+        }
+    }
+
+#else // ^^ Exceptions are enabled // Exceptions are disabled vv
+    std::string ExceptionTranslatorRegistry::translateActiveException() const {
+        CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+    }
+
+    std::string ExceptionTranslatorRegistry::tryTranslators() const {
+        CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+    }
+#endif
+
+}
+// end catch_exception_translator_registry.cpp
+// start catch_fatal_condition.cpp
+
+#include <algorithm>
+
+#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+namespace Catch {
+
+    // If neither SEH nor signal handling is required, the handler impls
+    // do not have to do anything, and can be empty.
+    void FatalConditionHandler::engage_platform() {}
+    void FatalConditionHandler::disengage_platform() {}
+    FatalConditionHandler::FatalConditionHandler() = default;
+    FatalConditionHandler::~FatalConditionHandler() = default;
+
+} // end namespace Catch
+
+#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )
+#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
+#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+namespace {
+    //! Signals fatal error message to the run context
+    void reportFatal( char const * const message ) {
+        Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
+    }
+
+    //! Minimal size Catch2 needs for its own fatal error handling.
+    //! Picked anecdotally, so it might not be sufficient on all
+    //! platforms, and for all configurations.
+    constexpr std::size_t minStackSizeForErrors = 32 * 1024;
+} // end unnamed namespace
+
+#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
+
+#if defined( CATCH_CONFIG_WINDOWS_SEH )
+
+namespace Catch {
+
+    struct SignalDefs { DWORD id; const char* name; };
+
+    // There is no 1-1 mapping between signals and windows exceptions.
+    // Windows can easily distinguish between SO and SigSegV,
+    // but SigInt, SigTerm, etc are handled differently.
+    static SignalDefs signalDefs[] = {
+        { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  "SIGILL - Illegal instruction signal" },
+        { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
+        { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
+        { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
+    };
+
+    static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
+        for (auto const& def : signalDefs) {
+            if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
+                reportFatal(def.name);
+            }
+        }
+        // If its not an exception we care about, pass it along.
+        // This stops us from eating debugger breaks etc.
+        return EXCEPTION_CONTINUE_SEARCH;
+    }
+
+    // Since we do not support multiple instantiations, we put these
+    // into global variables and rely on cleaning them up in outlined
+    // constructors/destructors
+    static PVOID exceptionHandlerHandle = nullptr;
+
+    // For MSVC, we reserve part of the stack memory for handling
+    // memory overflow structured exception.
+    FatalConditionHandler::FatalConditionHandler() {
+        ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);
+        if (!SetThreadStackGuarantee(&guaranteeSize)) {
+            // We do not want to fully error out, because needing
+            // the stack reserve should be rare enough anyway.
+            Catch::cerr()
+                << "Failed to reserve piece of stack."
+                << " Stack overflows will not be reported successfully.";
+        }
+    }
+
+    // We do not attempt to unset the stack guarantee, because
+    // Windows does not support lowering the stack size guarantee.
+    FatalConditionHandler::~FatalConditionHandler() = default;
+
+    void FatalConditionHandler::engage_platform() {
+        // Register as first handler in current chain
+        exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
+        if (!exceptionHandlerHandle) {
+            CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
+        }
+    }
+
+    void FatalConditionHandler::disengage_platform() {
+        if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
+            CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
+        }
+        exceptionHandlerHandle = nullptr;
+    }
+
+} // end namespace Catch
+
+#endif // CATCH_CONFIG_WINDOWS_SEH
+
+#if defined( CATCH_CONFIG_POSIX_SIGNALS )
+
+#include <signal.h>
+
+namespace Catch {
+
+    struct SignalDefs {
+        int id;
+        const char* name;
+    };
+
+    static SignalDefs signalDefs[] = {
+        { SIGINT,  "SIGINT - Terminal interrupt signal" },
+        { SIGILL,  "SIGILL - Illegal instruction signal" },
+        { SIGFPE,  "SIGFPE - Floating point error signal" },
+        { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+        { SIGTERM, "SIGTERM - Termination request signal" },
+        { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+    };
+
+// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
+// which is zero initialization, but not explicit. We want to avoid
+// that.
+#if defined(__GNUC__)
+#    pragma GCC diagnostic push
+#    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+    static char* altStackMem = nullptr;
+    static std::size_t altStackSize = 0;
+    static stack_t oldSigStack{};
+    static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
+
+    static void restorePreviousSignalHandlers() {
+        // We set signal handlers back to the previous ones. Hopefully
+        // nobody overwrote them in the meantime, and doesn't expect
+        // their signal handlers to live past ours given that they
+        // installed them after ours..
+        for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
+            sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
+        }
+        // Return the old stack
+        sigaltstack(&oldSigStack, nullptr);
+    }
+
+    static void handleSignal( int sig ) {
+        char const * name = "<unknown signal>";
+        for (auto const& def : signalDefs) {
+            if (sig == def.id) {
+                name = def.name;
+                break;
+            }
+        }
+        // We need to restore previous signal handlers and let them do
+        // their thing, so that the users can have the debugger break
+        // when a signal is raised, and so on.
+        restorePreviousSignalHandlers();
+        reportFatal( name );
+        raise( sig );
+    }
+
+    FatalConditionHandler::FatalConditionHandler() {
+        assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
+        if (altStackSize == 0) {
+            altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);
+        }
+        altStackMem = new char[altStackSize]();
+    }
+
+    FatalConditionHandler::~FatalConditionHandler() {
+        delete[] altStackMem;
+        // We signal that another instance can be constructed by zeroing
+        // out the pointer.
+        altStackMem = nullptr;
+    }
+
+    void FatalConditionHandler::engage_platform() {
+        stack_t sigStack;
+        sigStack.ss_sp = altStackMem;
+        sigStack.ss_size = altStackSize;
+        sigStack.ss_flags = 0;
+        sigaltstack(&sigStack, &oldSigStack);
+        struct sigaction sa = { };
+
+        sa.sa_handler = handleSignal;
+        sa.sa_flags = SA_ONSTACK;
+        for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
+            sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
+        }
+    }
+
+#if defined(__GNUC__)
+#    pragma GCC diagnostic pop
+#endif
+
+    void FatalConditionHandler::disengage_platform() {
+        restorePreviousSignalHandlers();
+    }
+
+} // end namespace Catch
+
+#endif // CATCH_CONFIG_POSIX_SIGNALS
+// end catch_fatal_condition.cpp
+// start catch_generators.cpp
+
+#include <limits>
+#include <set>
+
+namespace Catch {
+
+IGeneratorTracker::~IGeneratorTracker() {}
+
+const char* GeneratorException::what() const noexcept {
+    return m_msg;
+}
+
+namespace Generators {
+
+    GeneratorUntypedBase::~GeneratorUntypedBase() {}
+
+    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
+    }
+
+} // namespace Generators
+} // namespace Catch
+// end catch_generators.cpp
+// start catch_interfaces_capture.cpp
+
+namespace Catch {
+    IResultCapture::~IResultCapture() = default;
+}
+// end catch_interfaces_capture.cpp
+// start catch_interfaces_config.cpp
+
+namespace Catch {
+    IConfig::~IConfig() = default;
+}
+// end catch_interfaces_config.cpp
+// start catch_interfaces_exception.cpp
+
+namespace Catch {
+    IExceptionTranslator::~IExceptionTranslator() = default;
+    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
+}
+// end catch_interfaces_exception.cpp
+// start catch_interfaces_registry_hub.cpp
+
+namespace Catch {
+    IRegistryHub::~IRegistryHub() = default;
+    IMutableRegistryHub::~IMutableRegistryHub() = default;
+}
+// end catch_interfaces_registry_hub.cpp
+// start catch_interfaces_reporter.cpp
+
+// start catch_reporter_listening.h
+
+namespace Catch {
+
+    class ListeningReporter : public IStreamingReporter {
+        using Reporters = std::vector<IStreamingReporterPtr>;
+        Reporters m_listeners;
+        IStreamingReporterPtr m_reporter = nullptr;
+        ReporterPreferences m_preferences;
+
+    public:
+        ListeningReporter();
+
+        void addListener( IStreamingReporterPtr&& listener );
+        void addReporter( IStreamingReporterPtr&& reporter );
+
+    public: // IStreamingReporter
+
+        ReporterPreferences getPreferences() const override;
+
+        void noMatchingTestCases( std::string const& spec ) override;
+
+        void reportInvalidArguments(std::string const&arg) override;
+
+        static std::set<Verbosity> getSupportedVerbosities();
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+        void benchmarkPreparing(std::string const& name) override;
+        void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
+        void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
+        void benchmarkFailed(std::string const&) override;
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+        void testRunStarting( TestRunInfo const& testRunInfo ) override;
+        void testGroupStarting( GroupInfo const& groupInfo ) override;
+        void testCaseStarting( TestCaseInfo const& testInfo ) override;
+        void sectionStarting( SectionInfo const& sectionInfo ) override;
+        void assertionStarting( AssertionInfo const& assertionInfo ) override;
+
+        // The return value indicates if the messages buffer should be cleared:
+        bool assertionEnded( AssertionStats const& assertionStats ) override;
+        void sectionEnded( SectionStats const& sectionStats ) override;
+        void testCaseEnded( TestCaseStats const& testCaseStats ) override;
+        void testGroupEnded( TestGroupStats const& testGroupStats ) override;
+        void testRunEnded( TestRunStats const& testRunStats ) override;
+
+        void skipTest( TestCaseInfo const& testInfo ) override;
+        bool isMulti() const override;
+
+    };
+
+} // end namespace Catch
+
+// end catch_reporter_listening.h
+namespace Catch {
+
+    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
+    :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
+    :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+    std::ostream& ReporterConfig::stream() const { return *m_stream; }
+    IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
+
+    TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
+
+    GroupInfo::GroupInfo(  std::string const& _name,
+                           std::size_t _groupIndex,
+                           std::size_t _groupsCount )
+    :   name( _name ),
+        groupIndex( _groupIndex ),
+        groupsCounts( _groupsCount )
+    {}
+
+     AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
+                                     std::vector<MessageInfo> const& _infoMessages,
+                                     Totals const& _totals )
+    :   assertionResult( _assertionResult ),
+        infoMessages( _infoMessages ),
+        totals( _totals )
+    {
+        assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
+
+        if( assertionResult.hasMessage() ) {
+            // Copy message into messages list.
+            // !TBD This should have been done earlier, somewhere
+            MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+            builder << assertionResult.getMessage();
+            builder.m_info.message = builder.m_stream.str();
+
+            infoMessages.push_back( builder.m_info );
+        }
+    }
+
+     AssertionStats::~AssertionStats() = default;
+
+    SectionStats::SectionStats(  SectionInfo const& _sectionInfo,
+                                 Counts const& _assertions,
+                                 double _durationInSeconds,
+                                 bool _missingAssertions )
+    :   sectionInfo( _sectionInfo ),
+        assertions( _assertions ),
+        durationInSeconds( _durationInSeconds ),
+        missingAssertions( _missingAssertions )
+    {}
+
+    SectionStats::~SectionStats() = default;
+
+    TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,
+                                   Totals const& _totals,
+                                   std::string const& _stdOut,
+                                   std::string const& _stdErr,
+                                   bool _aborting )
+    : testInfo( _testInfo ),
+        totals( _totals ),
+        stdOut( _stdOut ),
+        stdErr( _stdErr ),
+        aborting( _aborting )
+    {}
+
+    TestCaseStats::~TestCaseStats() = default;
+
+    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
+                                    Totals const& _totals,
+                                    bool _aborting )
+    :   groupInfo( _groupInfo ),
+        totals( _totals ),
+        aborting( _aborting )
+    {}
+
+    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
+    :   groupInfo( _groupInfo ),
+        aborting( false )
+    {}
+
+    TestGroupStats::~TestGroupStats() = default;
+
+    TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,
+                    Totals const& _totals,
+                    bool _aborting )
+    :   runInfo( _runInfo ),
+        totals( _totals ),
+        aborting( _aborting )
+    {}
+
+    TestRunStats::~TestRunStats() = default;
+
+    void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
+    bool IStreamingReporter::isMulti() const { return false; }
+
+    IReporterFactory::~IReporterFactory() = default;
+    IReporterRegistry::~IReporterRegistry() = default;
+
+} // end namespace Catch
+// end catch_interfaces_reporter.cpp
+// start catch_interfaces_runner.cpp
+
+namespace Catch {
+    IRunner::~IRunner() = default;
+}
+// end catch_interfaces_runner.cpp
+// start catch_interfaces_testcase.cpp
+
+namespace Catch {
+    ITestInvoker::~ITestInvoker() = default;
+    ITestCaseRegistry::~ITestCaseRegistry() = default;
+}
+// end catch_interfaces_testcase.cpp
+// start catch_leak_detector.cpp
+
+#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
+#include <crtdbg.h>
+
+namespace Catch {
+
+    LeakDetector::LeakDetector() {
+        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+        flag |= _CRTDBG_ALLOC_MEM_DF;
+        _CrtSetDbgFlag(flag);
+        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+        // Change this to leaking allocation's number to break there
+        _CrtSetBreakAlloc(-1);
+    }
+}
+
+#else
+
+    Catch::LeakDetector::LeakDetector() {}
+
+#endif
+
+Catch::LeakDetector::~LeakDetector() {
+    Catch::cleanUp();
+}
+// end catch_leak_detector.cpp
+// start catch_list.cpp
+
+// start catch_list.h
+
+#include <set>
+
+namespace Catch {
+
+    std::size_t listTests( Config const& config );
+
+    std::size_t listTestsNamesOnly( Config const& config );
+
+    struct TagInfo {
+        void add( std::string const& spelling );
+        std::string all() const;
+
+        std::set<std::string> spellings;
+        std::size_t count = 0;
+    };
+
+    std::size_t listTags( Config const& config );
+
+    std::size_t listReporters();
+
+    Option<std::size_t> list( std::shared_ptr<Config> const& config );
+
+} // end namespace Catch
+
+// end catch_list.h
+// start catch_text.h
+
+namespace Catch {
+    using namespace clara::TextFlow;
+}
+
+// end catch_text.h
+#include <limits>
+#include <algorithm>
+#include <iomanip>
+
+namespace Catch {
+
+    std::size_t listTests( Config const& config ) {
+        TestSpec const& testSpec = config.testSpec();
+        if( config.hasTestFilters() )
+            Catch::cout() << "Matching test cases:\n";
+        else {
+            Catch::cout() << "All available test cases:\n";
+        }
+
+        auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+        for( auto const& testCaseInfo : matchedTestCases ) {
+            Colour::Code colour = testCaseInfo.isHidden()
+                ? Colour::SecondaryText
+                : Colour::None;
+            Colour colourGuard( colour );
+
+            Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
+            if( config.verbosity() >= Verbosity::High ) {
+                Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
+                std::string description = testCaseInfo.description;
+                if( description.empty() )
+                    description = "(NO DESCRIPTION)";
+                Catch::cout() << Column( description ).indent(4) << std::endl;
+            }
+            if( !testCaseInfo.tags.empty() )
+                Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
+        }
+
+        if( !config.hasTestFilters() )
+            Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
+        else
+            Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
+        return matchedTestCases.size();
+    }
+
+    std::size_t listTestsNamesOnly( Config const& config ) {
+        TestSpec const& testSpec = config.testSpec();
+        std::size_t matchedTests = 0;
+        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+        for( auto const& testCaseInfo : matchedTestCases ) {
+            matchedTests++;
+            if( startsWith( testCaseInfo.name, '#' ) )
+               Catch::cout() << '"' << testCaseInfo.name << '"';
+            else
+               Catch::cout() << testCaseInfo.name;
+            if ( config.verbosity() >= Verbosity::High )
+                Catch::cout() << "\t@" << testCaseInfo.lineInfo;
+            Catch::cout() << std::endl;
+        }
+        return matchedTests;
+    }
+
+    void TagInfo::add( std::string const& spelling ) {
+        ++count;
+        spellings.insert( spelling );
+    }
+
+    std::string TagInfo::all() const {
+        size_t size = 0;
+        for (auto const& spelling : spellings) {
+            // Add 2 for the brackes
+            size += spelling.size() + 2;
+        }
+
+        std::string out; out.reserve(size);
+        for (auto const& spelling : spellings) {
+            out += '[';
+            out += spelling;
+            out += ']';
+        }
+        return out;
+    }
+
+    std::size_t listTags( Config const& config ) {
+        TestSpec const& testSpec = config.testSpec();
+        if( config.hasTestFilters() )
+            Catch::cout() << "Tags for matching test cases:\n";
+        else {
+            Catch::cout() << "All available tags:\n";
+        }
+
+        std::map<std::string, TagInfo> tagCounts;
+
+        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+        for( auto const& testCase : matchedTestCases ) {
+            for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
+                std::string lcaseTagName = toLower( tagName );
+                auto countIt = tagCounts.find( lcaseTagName );
+                if( countIt == tagCounts.end() )
+                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+                countIt->second.add( tagName );
+            }
+        }
+
+        for( auto const& tagCount : tagCounts ) {
+            ReusableStringStream rss;
+            rss << "  " << std::setw(2) << tagCount.second.count << "  ";
+            auto str = rss.str();
+            auto wrapper = Column( tagCount.second.all() )
+                                                    .initialIndent( 0 )
+                                                    .indent( str.size() )
+                                                    .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
+            Catch::cout() << str << wrapper << '\n';
+        }
+        Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
+        return tagCounts.size();
+    }
+
+    std::size_t listReporters() {
+        Catch::cout() << "Available reporters:\n";
+        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+        std::size_t maxNameLen = 0;
+        for( auto const& factoryKvp : factories )
+            maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
+
+        for( auto const& factoryKvp : factories ) {
+            Catch::cout()
+                    << Column( factoryKvp.first + ":" )
+                            .indent(2)
+                            .width( 5+maxNameLen )
+                    +  Column( factoryKvp.second->getDescription() )
+                            .initialIndent(0)
+                            .indent(2)
+                            .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
+                    << "\n";
+        }
+        Catch::cout() << std::endl;
+        return factories.size();
+    }
+
+    Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
+        Option<std::size_t> listedCount;
+        getCurrentMutableContext().setConfig( config );
+        if( config->listTests() )
+            listedCount = listedCount.valueOr(0) + listTests( *config );
+        if( config->listTestNamesOnly() )
+            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
+        if( config->listTags() )
+            listedCount = listedCount.valueOr(0) + listTags( *config );
+        if( config->listReporters() )
+            listedCount = listedCount.valueOr(0) + listReporters();
+        return listedCount;
+    }
+
+} // end namespace Catch
+// end catch_list.cpp
+// start catch_matchers.cpp
+
+namespace Catch {
+namespace Matchers {
+    namespace Impl {
+
+        std::string MatcherUntypedBase::toString() const {
+            if( m_cachedToString.empty() )
+                m_cachedToString = describe();
+            return m_cachedToString;
+        }
+
+        MatcherUntypedBase::~MatcherUntypedBase() = default;
+
+    } // namespace Impl
+} // namespace Matchers
+
+using namespace Matchers;
+using Matchers::Impl::MatcherBase;
+
+} // namespace Catch
+// end catch_matchers.cpp
+// start catch_matchers_exception.cpp
+
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+bool ExceptionMessageMatcher::match(std::exception const& ex) const {
+    return ex.what() == m_message;
+}
+
+std::string ExceptionMessageMatcher::describe() const {
+    return "exception message matches \"" + m_message + "\"";
+}
+
+}
+Exception::ExceptionMessageMatcher Message(std::string const& message) {
+    return Exception::ExceptionMessageMatcher(message);
+}
+
+// namespace Exception
+} // namespace Matchers
+} // namespace Catch
+// end catch_matchers_exception.cpp
+// start catch_matchers_floating.cpp
+
+// start catch_polyfills.hpp
+
+namespace Catch {
+    bool isnan(float f);
+    bool isnan(double d);
+}
+
+// end catch_polyfills.hpp
+// start catch_to_string.hpp
+
+#include <string>
+
+namespace Catch {
+    template <typename T>
+    std::string to_string(T const& t) {
+#if defined(CATCH_CONFIG_CPP11_TO_STRING)
+        return std::to_string(t);
+#else
+        ReusableStringStream rss;
+        rss << t;
+        return rss.str();
+#endif
+    }
+} // end namespace Catch
+
+// end catch_to_string.hpp
+#include <algorithm>
+#include <cmath>
+#include <cstdlib>
+#include <cstdint>
+#include <cstring>
+#include <sstream>
+#include <type_traits>
+#include <iomanip>
+#include <limits>
+
+namespace Catch {
+namespace {
+
+    int32_t convert(float f) {
+        static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
+        int32_t i;
+        std::memcpy(&i, &f, sizeof(f));
+        return i;
+    }
+
+    int64_t convert(double d) {
+        static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
+        int64_t i;
+        std::memcpy(&i, &d, sizeof(d));
+        return i;
+    }
+
+    template <typename FP>
+    bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
+        // Comparison with NaN should always be false.
+        // This way we can rule it out before getting into the ugly details
+        if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
+            return false;
+        }
+
+        auto lc = convert(lhs);
+        auto rc = convert(rhs);
+
+        if ((lc < 0) != (rc < 0)) {
+            // Potentially we can have +0 and -0
+            return lhs == rhs;
+        }
+
+        // static cast as a workaround for IBM XLC
+        auto ulpDiff = std::abs(static_cast<FP>(lc - rc));
+        return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
+    }
+
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+
+    float nextafter(float x, float y) {
+        return ::nextafterf(x, y);
+    }
+
+    double nextafter(double x, double y) {
+        return ::nextafter(x, y);
+    }
+
+#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
+
+template <typename FP>
+FP step(FP start, FP direction, uint64_t steps) {
+    for (uint64_t i = 0; i < steps; ++i) {
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+        start = Catch::nextafter(start, direction);
+#else
+        start = std::nextafter(start, direction);
+#endif
+    }
+    return start;
+}
+
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+    return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+}
+
+template <typename FloatingPoint>
+void write(std::ostream& out, FloatingPoint num) {
+    out << std::scientific
+        << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
+        << num;
+}
+
+} // end anonymous namespace
+
+namespace Matchers {
+namespace Floating {
+
+    enum class FloatingPointKind : uint8_t {
+        Float,
+        Double
+    };
+
+    WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
+        :m_target{ target }, m_margin{ margin } {
+        CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
+            << " Margin has to be non-negative.");
+    }
+
+    // Performs equivalent check of std::fabs(lhs - rhs) <= margin
+    // But without the subtraction to allow for INFINITY in comparison
+    bool WithinAbsMatcher::match(double const& matchee) const {
+        return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
+    }
+
+    std::string WithinAbsMatcher::describe() const {
+        return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
+    }
+
+    WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
+        :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
+        CATCH_ENFORCE(m_type == FloatingPointKind::Double
+                   || m_ulps < (std::numeric_limits<uint32_t>::max)(),
+            "Provided ULP is impossibly large for a float comparison.");
+    }
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+// Clang <3.5 reports on the default branch in the switch below
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
+    bool WithinUlpsMatcher::match(double const& matchee) const {
+        switch (m_type) {
+        case FloatingPointKind::Float:
+            return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
+        case FloatingPointKind::Double:
+            return almostEqualUlps<double>(matchee, m_target, m_ulps);
+        default:
+            CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
+        }
+    }
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+    std::string WithinUlpsMatcher::describe() const {
+        std::stringstream ret;
+
+        ret << "is within " << m_ulps << " ULPs of ";
+
+        if (m_type == FloatingPointKind::Float) {
+            write(ret, static_cast<float>(m_target));
+            ret << 'f';
+        } else {
+            write(ret, m_target);
+        }
+
+        ret << " ([";
+        if (m_type == FloatingPointKind::Double) {
+            write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
+            ret << ", ";
+            write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
+        } else {
+            // We have to cast INFINITY to float because of MinGW, see #1782
+            write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
+            ret << ", ";
+            write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
+        }
+        ret << "])";
+
+        return ret.str();
+    }
+
+    WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
+        m_target(target),
+        m_epsilon(epsilon){
+        CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon <  0 does not make sense.");
+        CATCH_ENFORCE(m_epsilon  < 1., "Relative comparison with epsilon >= 1 does not make sense.");
+    }
+
+    bool WithinRelMatcher::match(double const& matchee) const {
+        const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
+        return marginComparison(matchee, m_target,
+                                std::isinf(relMargin)? 0 : relMargin);
+    }
+
+    std::string WithinRelMatcher::describe() const {
+        Catch::ReusableStringStream sstr;
+        sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
+        return sstr.str();
+    }
+
+}// namespace Floating
+
+Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
+    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
+}
+
+Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
+    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
+}
+
+Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
+    return Floating::WithinAbsMatcher(target, margin);
+}
+
+Floating::WithinRelMatcher WithinRel(double target, double eps) {
+    return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(double target) {
+    return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
+}
+
+Floating::WithinRelMatcher WithinRel(float target, float eps) {
+    return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(float target) {
+    return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
+}
+
+} // namespace Matchers
+} // namespace Catch
+// end catch_matchers_floating.cpp
+// start catch_matchers_generic.cpp
+
+std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
+    if (desc.empty()) {
+        return "matches undescribed predicate";
+    } else {
+        return "matches predicate: \"" + desc + '"';
+    }
+}
+// end catch_matchers_generic.cpp
+// start catch_matchers_string.cpp
+
+#include <regex>
+
+namespace Catch {
+namespace Matchers {
+
+    namespace StdString {
+
+        CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
+        :   m_caseSensitivity( caseSensitivity ),
+            m_str( adjustString( str ) )
+        {}
+        std::string CasedString::adjustString( std::string const& str ) const {
+            return m_caseSensitivity == CaseSensitive::No
+                   ? toLower( str )
+                   : str;
+        }
+        std::string CasedString::caseSensitivitySuffix() const {
+            return m_caseSensitivity == CaseSensitive::No
+                   ? " (case insensitive)"
+                   : std::string();
+        }
+
+        StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
+        : m_comparator( comparator ),
+          m_operation( operation ) {
+        }
+
+        std::string StringMatcherBase::describe() const {
+            std::string description;
+            description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
+                                        m_comparator.caseSensitivitySuffix().size());
+            description += m_operation;
+            description += ": \"";
+            description += m_comparator.m_str;
+            description += "\"";
+            description += m_comparator.caseSensitivitySuffix();
+            return description;
+        }
+
+        EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
+
+        bool EqualsMatcher::match( std::string const& source ) const {
+            return m_comparator.adjustString( source ) == m_comparator.m_str;
+        }
+
+        ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
+
+        bool ContainsMatcher::match( std::string const& source ) const {
+            return contains( m_comparator.adjustString( source ), m_comparator.m_str );
+        }
+
+        StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
+
+        bool StartsWithMatcher::match( std::string const& source ) const {
+            return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
+        }
+
+        EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
+
+        bool EndsWithMatcher::match( std::string const& source ) const {
+            return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
+        }
+
+        RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
+
+        bool RegexMatcher::match(std::string const& matchee) const {
+            auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
+            if (m_caseSensitivity == CaseSensitive::Choice::No) {
+                flags |= std::regex::icase;
+            }
+            auto reg = std::regex(m_regex, flags);
+            return std::regex_match(matchee, reg);
+        }
+
+        std::string RegexMatcher::describe() const {
+            return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
+        }
+
+    } // namespace StdString
+
+    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+
+    StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
+        return StdString::RegexMatcher(regex, caseSensitivity);
+    }
+
+} // namespace Matchers
+} // namespace Catch
+// end catch_matchers_string.cpp
+// start catch_message.cpp
+
+// start catch_uncaught_exceptions.h
+
+namespace Catch {
+    bool uncaught_exceptions();
+} // end namespace Catch
+
+// end catch_uncaught_exceptions.h
+#include <cassert>
+#include <stack>
+
+namespace Catch {
+
+    MessageInfo::MessageInfo(   StringRef const& _macroName,
+                                SourceLineInfo const& _lineInfo,
+                                ResultWas::OfType _type )
+    :   macroName( _macroName ),
+        lineInfo( _lineInfo ),
+        type( _type ),
+        sequence( ++globalCount )
+    {}
+
+    bool MessageInfo::operator==( MessageInfo const& other ) const {
+        return sequence == other.sequence;
+    }
+
+    bool MessageInfo::operator<( MessageInfo const& other ) const {
+        return sequence < other.sequence;
+    }
+
+    // This may need protecting if threading support is added
+    unsigned int MessageInfo::globalCount = 0;
+
+    ////////////////////////////////////////////////////////////////////////////
+
+    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
+                                           SourceLineInfo const& lineInfo,
+                                           ResultWas::OfType type )
+        :m_info(macroName, lineInfo, type) {}
+
+    ////////////////////////////////////////////////////////////////////////////
+
+    ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+    : m_info( builder.m_info ), m_moved()
+    {
+        m_info.message = builder.m_stream.str();
+        getResultCapture().pushScopedMessage( m_info );
+    }
+
+    ScopedMessage::ScopedMessage( ScopedMessage&& old )
+    : m_info( old.m_info ), m_moved()
+    {
+        old.m_moved = true;
+    }
+
+    ScopedMessage::~ScopedMessage() {
+        if ( !uncaught_exceptions() && !m_moved ){
+            getResultCapture().popScopedMessage(m_info);
+        }
+    }
+
+    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
+        auto trimmed = [&] (size_t start, size_t end) {
+            while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
+                ++start;
+            }
+            while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
+                --end;
+            }
+            return names.substr(start, end - start + 1);
+        };
+        auto skipq = [&] (size_t start, char quote) {
+            for (auto i = start + 1; i < names.size() ; ++i) {
+                if (names[i] == quote)
+                    return i;
+                if (names[i] == '\\')
+                    ++i;
+            }
+            CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
+        };
+
+        size_t start = 0;
+        std::stack<char> openings;
+        for (size_t pos = 0; pos < names.size(); ++pos) {
+            char c = names[pos];
+            switch (c) {
+            case '[':
+            case '{':
+            case '(':
+            // It is basically impossible to disambiguate between
+            // comparison and start of template args in this context
+//            case '<':
+                openings.push(c);
+                break;
+            case ']':
+            case '}':
+            case ')':
+//           case '>':
+                openings.pop();
+                break;
+            case '"':
+            case '\'':
+                pos = skipq(pos, c);
+                break;
+            case ',':
+                if (start != pos && openings.empty()) {
+                    m_messages.emplace_back(macroName, lineInfo, resultType);
+                    m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
+                    m_messages.back().message += " := ";
+                    start = pos;
+                }
+            }
+        }
+        assert(openings.empty() && "Mismatched openings");
+        m_messages.emplace_back(macroName, lineInfo, resultType);
+        m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
+        m_messages.back().message += " := ";
+    }
+    Capturer::~Capturer() {
+        if ( !uncaught_exceptions() ){
+            assert( m_captured == m_messages.size() );
+            for( size_t i = 0; i < m_captured; ++i  )
+                m_resultCapture.popScopedMessage( m_messages[i] );
+        }
+    }
+
+    void Capturer::captureValue( size_t index, std::string const& value ) {
+        assert( index < m_messages.size() );
+        m_messages[index].message += value;
+        m_resultCapture.pushScopedMessage( m_messages[index] );
+        m_captured++;
+    }
+
+} // end namespace Catch
+// end catch_message.cpp
+// start catch_output_redirect.cpp
+
+// start catch_output_redirect.h
+#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
+#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
+
+#include <cstdio>
+#include <iosfwd>
+#include <string>
+
+namespace Catch {
+
+    class RedirectedStream {
+        std::ostream& m_originalStream;
+        std::ostream& m_redirectionStream;
+        std::streambuf* m_prevBuf;
+
+    public:
+        RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
+        ~RedirectedStream();
+    };
+
+    class RedirectedStdOut {
+        ReusableStringStream m_rss;
+        RedirectedStream m_cout;
+    public:
+        RedirectedStdOut();
+        auto str() const -> std::string;
+    };
+
+    // StdErr has two constituent streams in C++, std::cerr and std::clog
+    // This means that we need to redirect 2 streams into 1 to keep proper
+    // order of writes
+    class RedirectedStdErr {
+        ReusableStringStream m_rss;
+        RedirectedStream m_cerr;
+        RedirectedStream m_clog;
+    public:
+        RedirectedStdErr();
+        auto str() const -> std::string;
+    };
+
+    class RedirectedStreams {
+    public:
+        RedirectedStreams(RedirectedStreams const&) = delete;
+        RedirectedStreams& operator=(RedirectedStreams const&) = delete;
+        RedirectedStreams(RedirectedStreams&&) = delete;
+        RedirectedStreams& operator=(RedirectedStreams&&) = delete;
+
+        RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
+        ~RedirectedStreams();
+    private:
+        std::string& m_redirectedCout;
+        std::string& m_redirectedCerr;
+        RedirectedStdOut m_redirectedStdOut;
+        RedirectedStdErr m_redirectedStdErr;
+    };
+
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
+    // Windows's implementation of std::tmpfile is terrible (it tries
+    // to create a file inside system folder, thus requiring elevated
+    // privileges for the binary), so we have to use tmpnam(_s) and
+    // create the file ourselves there.
+    class TempFile {
+    public:
+        TempFile(TempFile const&) = delete;
+        TempFile& operator=(TempFile const&) = delete;
+        TempFile(TempFile&&) = delete;
+        TempFile& operator=(TempFile&&) = delete;
+
+        TempFile();
+        ~TempFile();
+
+        std::FILE* getFile();
+        std::string getContents();
+
+    private:
+        std::FILE* m_file = nullptr;
+    #if defined(_MSC_VER)
+        char m_buffer[L_tmpnam] = { 0 };
+    #endif
+    };
+
+    class OutputRedirect {
+    public:
+        OutputRedirect(OutputRedirect const&) = delete;
+        OutputRedirect& operator=(OutputRedirect const&) = delete;
+        OutputRedirect(OutputRedirect&&) = delete;
+        OutputRedirect& operator=(OutputRedirect&&) = delete;
+
+        OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
+        ~OutputRedirect();
+
+    private:
+        int m_originalStdout = -1;
+        int m_originalStderr = -1;
+        TempFile m_stdoutFile;
+        TempFile m_stderrFile;
+        std::string& m_stdoutDest;
+        std::string& m_stderrDest;
+    };
+
+#endif
+
+} // end namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
+// end catch_output_redirect.h
+#include <cstdio>
+#include <cstring>
+#include <fstream>
+#include <sstream>
+#include <stdexcept>
+
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #include <io.h>      //_dup and _dup2
+    #define dup _dup
+    #define dup2 _dup2
+    #define fileno _fileno
+    #else
+    #include <unistd.h>  // dup and dup2
+    #endif
+#endif
+
+namespace Catch {
+
+    RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
+    :   m_originalStream( originalStream ),
+        m_redirectionStream( redirectionStream ),
+        m_prevBuf( m_originalStream.rdbuf() )
+    {
+        m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
+    }
+
+    RedirectedStream::~RedirectedStream() {
+        m_originalStream.rdbuf( m_prevBuf );
+    }
+
+    RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
+    auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
+
+    RedirectedStdErr::RedirectedStdErr()
+    :   m_cerr( Catch::cerr(), m_rss.get() ),
+        m_clog( Catch::clog(), m_rss.get() )
+    {}
+    auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
+
+    RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
+    :   m_redirectedCout(redirectedCout),
+        m_redirectedCerr(redirectedCerr)
+    {}
+
+    RedirectedStreams::~RedirectedStreams() {
+        m_redirectedCout += m_redirectedStdOut.str();
+        m_redirectedCerr += m_redirectedStdErr.str();
+    }
+
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
+#if defined(_MSC_VER)
+    TempFile::TempFile() {
+        if (tmpnam_s(m_buffer)) {
+            CATCH_RUNTIME_ERROR("Could not get a temp filename");
+        }
+        if (fopen_s(&m_file, m_buffer, "w+")) {
+            char buffer[100];
+            if (strerror_s(buffer, errno)) {
+                CATCH_RUNTIME_ERROR("Could not translate errno to a string");
+            }
+            CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
+        }
+    }
+#else
+    TempFile::TempFile() {
+        m_file = std::tmpfile();
+        if (!m_file) {
+            CATCH_RUNTIME_ERROR("Could not create a temp file.");
+        }
+    }
+
+#endif
+
+    TempFile::~TempFile() {
+         // TBD: What to do about errors here?
+         std::fclose(m_file);
+         // We manually create the file on Windows only, on Linux
+         // it will be autodeleted
+#if defined(_MSC_VER)
+         std::remove(m_buffer);
+#endif
+    }
+
+    FILE* TempFile::getFile() {
+        return m_file;
+    }
+
+    std::string TempFile::getContents() {
+        std::stringstream sstr;
+        char buffer[100] = {};
+        std::rewind(m_file);
+        while (std::fgets(buffer, sizeof(buffer), m_file)) {
+            sstr << buffer;
+        }
+        return sstr.str();
+    }
+
+    OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
+        m_originalStdout(dup(1)),
+        m_originalStderr(dup(2)),
+        m_stdoutDest(stdout_dest),
+        m_stderrDest(stderr_dest) {
+        dup2(fileno(m_stdoutFile.getFile()), 1);
+        dup2(fileno(m_stderrFile.getFile()), 2);
+    }
+
+    OutputRedirect::~OutputRedirect() {
+        Catch::cout() << std::flush;
+        fflush(stdout);
+        // Since we support overriding these streams, we flush cerr
+        // even though std::cerr is unbuffered
+        Catch::cerr() << std::flush;
+        Catch::clog() << std::flush;
+        fflush(stderr);
+
+        dup2(m_originalStdout, 1);
+        dup2(m_originalStderr, 2);
+
+        m_stdoutDest += m_stdoutFile.getContents();
+        m_stderrDest += m_stderrFile.getContents();
+    }
+
+#endif // CATCH_CONFIG_NEW_CAPTURE
+
+} // namespace Catch
+
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #undef dup
+    #undef dup2
+    #undef fileno
+    #endif
+#endif
+// end catch_output_redirect.cpp
+// start catch_polyfills.cpp
+
+#include <cmath>
+
+namespace Catch {
+
+#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
+    bool isnan(float f) {
+        return std::isnan(f);
+    }
+    bool isnan(double d) {
+        return std::isnan(d);
+    }
+#else
+    // For now we only use this for embarcadero
+    bool isnan(float f) {
+        return std::_isnan(f);
+    }
+    bool isnan(double d) {
+        return std::_isnan(d);
+    }
+#endif
+
+} // end namespace Catch
+// end catch_polyfills.cpp
+// start catch_random_number_generator.cpp
+
+namespace Catch {
+
+namespace {
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4146) // we negate uint32 during the rotate
+#endif
+        // Safe rotr implementation thanks to John Regehr
+        uint32_t rotate_right(uint32_t val, uint32_t count) {
+            const uint32_t mask = 31;
+            count &= mask;
+            return (val >> count) | (val << (-count & mask));
+        }
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+}
+
+    SimplePcg32::SimplePcg32(result_type seed_) {
+        seed(seed_);
+    }
+
+    void SimplePcg32::seed(result_type seed_) {
+        m_state = 0;
+        (*this)();
+        m_state += seed_;
+        (*this)();
+    }
+
+    void SimplePcg32::discard(uint64_t skip) {
+        // We could implement this to run in O(log n) steps, but this
+        // should suffice for our use case.
+        for (uint64_t s = 0; s < skip; ++s) {
+            static_cast<void>((*this)());
+        }
+    }
+
+    SimplePcg32::result_type SimplePcg32::operator()() {
+        // prepare the output value
+        const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
+        const auto output = rotate_right(xorshifted, m_state >> 59u);
+
+        // advance state
+        m_state = m_state * 6364136223846793005ULL + s_inc;
+
+        return output;
+    }
+
+    bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+        return lhs.m_state == rhs.m_state;
+    }
+
+    bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+        return lhs.m_state != rhs.m_state;
+    }
+}
+// end catch_random_number_generator.cpp
+// start catch_registry_hub.cpp
+
+// start catch_test_case_registry_impl.h
+
+#include <vector>
+#include <set>
+#include <algorithm>
+#include <ios>
+
+namespace Catch {
+
+    class TestCase;
+    struct IConfig;
+
+    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
+
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config );
+    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+
+    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
+
+    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+    class TestRegistry : public ITestCaseRegistry {
+    public:
+        virtual ~TestRegistry() = default;
+
+        virtual void registerTest( TestCase const& testCase );
+
+        std::vector<TestCase> const& getAllTests() const override;
+        std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
+
+    private:
+        std::vector<TestCase> m_functions;
+        mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
+        mutable std::vector<TestCase> m_sortedFunctions;
+        std::size_t m_unnamedCount = 0;
+        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class TestInvokerAsFunction : public ITestInvoker {
+        void(*m_testAsFunction)();
+    public:
+        TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
+
+        void invoke() const override;
+    };
+
+    std::string extractClassName( StringRef const& classOrQualifiedMethodName );
+
+    ///////////////////////////////////////////////////////////////////////////
+
+} // end namespace Catch
+
+// end catch_test_case_registry_impl.h
+// start catch_reporter_registry.h
+
+#include <map>
+
+namespace Catch {
+
+    class ReporterRegistry : public IReporterRegistry {
+
+    public:
+
+        ~ReporterRegistry() override;
+
+        IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
+
+        void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
+        void registerListener( IReporterFactoryPtr const& factory );
+
+        FactoryMap const& getFactories() const override;
+        Listeners const& getListeners() const override;
+
+    private:
+        FactoryMap m_factories;
+        Listeners m_listeners;
+    };
+}
+
+// end catch_reporter_registry.h
+// start catch_tag_alias_registry.h
+
+// start catch_tag_alias.h
+
+#include <string>
+
+namespace Catch {
+
+    struct TagAlias {
+        TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
+
+        std::string tag;
+        SourceLineInfo lineInfo;
+    };
+
+} // end namespace Catch
+
+// end catch_tag_alias.h
+#include <map>
+
+namespace Catch {
+
+    class TagAliasRegistry : public ITagAliasRegistry {
+    public:
+        ~TagAliasRegistry() override;
+        TagAlias const* find( std::string const& alias ) const override;
+        std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
+        void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
+
+    private:
+        std::map<std::string, TagAlias> m_registry;
+    };
+
+} // end namespace Catch
+
+// end catch_tag_alias_registry.h
+// start catch_startup_exception_registry.h
+
+#include <vector>
+#include <exception>
+
+namespace Catch {
+
+    class StartupExceptionRegistry {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+    public:
+        void add(std::exception_ptr const& exception) noexcept;
+        std::vector<std::exception_ptr> const& getExceptions() const noexcept;
+    private:
+        std::vector<std::exception_ptr> m_exceptions;
+#endif
+    };
+
+} // end namespace Catch
+
+// end catch_startup_exception_registry.h
+// start catch_singletons.hpp
+
+namespace Catch {
+
+    struct ISingleton {
+        virtual ~ISingleton();
+    };
+
+    void addSingleton( ISingleton* singleton );
+    void cleanupSingletons();
+
+    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
+    class Singleton : SingletonImplT, public ISingleton {
+
+        static auto getInternal() -> Singleton* {
+            static Singleton* s_instance = nullptr;
+            if( !s_instance ) {
+                s_instance = new Singleton;
+                addSingleton( s_instance );
+            }
+            return s_instance;
+        }
+
+    public:
+        static auto get() -> InterfaceT const& {
+            return *getInternal();
+        }
+        static auto getMutable() -> MutableInterfaceT& {
+            return *getInternal();
+        }
+    };
+
+} // namespace Catch
+
+// end catch_singletons.hpp
+namespace Catch {
+
+    namespace {
+
+        class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
+                            private NonCopyable {
+
+        public: // IRegistryHub
+            RegistryHub() = default;
+            IReporterRegistry const& getReporterRegistry() const override {
+                return m_reporterRegistry;
+            }
+            ITestCaseRegistry const& getTestCaseRegistry() const override {
+                return m_testCaseRegistry;
+            }
+            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
+                return m_exceptionTranslatorRegistry;
+            }
+            ITagAliasRegistry const& getTagAliasRegistry() const override {
+                return m_tagAliasRegistry;
+            }
+            StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
+                return m_exceptionRegistry;
+            }
+
+        public: // IMutableRegistryHub
+            void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
+                m_reporterRegistry.registerReporter( name, factory );
+            }
+            void registerListener( IReporterFactoryPtr const& factory ) override {
+                m_reporterRegistry.registerListener( factory );
+            }
+            void registerTest( TestCase const& testInfo ) override {
+                m_testCaseRegistry.registerTest( testInfo );
+            }
+            void registerTranslator( const IExceptionTranslator* translator ) override {
+                m_exceptionTranslatorRegistry.registerTranslator( translator );
+            }
+            void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
+                m_tagAliasRegistry.add( alias, tag, lineInfo );
+            }
+            void registerStartupException() noexcept override {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+                m_exceptionRegistry.add(std::current_exception());
+#else
+                CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+#endif
+            }
+            IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
+                return m_enumValuesRegistry;
+            }
+
+        private:
+            TestRegistry m_testCaseRegistry;
+            ReporterRegistry m_reporterRegistry;
+            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+            TagAliasRegistry m_tagAliasRegistry;
+            StartupExceptionRegistry m_exceptionRegistry;
+            Detail::EnumValuesRegistry m_enumValuesRegistry;
+        };
+    }
+
+    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
+
+    IRegistryHub const& getRegistryHub() {
+        return RegistryHubSingleton::get();
+    }
+    IMutableRegistryHub& getMutableRegistryHub() {
+        return RegistryHubSingleton::getMutable();
+    }
+    void cleanUp() {
+        cleanupSingletons();
+        cleanUpContext();
+    }
+    std::string translateActiveException() {
+        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+    }
+
+} // end namespace Catch
+// end catch_registry_hub.cpp
+// start catch_reporter_registry.cpp
+
+namespace Catch {
+
+    ReporterRegistry::~ReporterRegistry() = default;
+
+    IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
+        auto it =  m_factories.find( name );
+        if( it == m_factories.end() )
+            return nullptr;
+        return it->second->create( ReporterConfig( config ) );
+    }
+
+    void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
+        m_factories.emplace(name, factory);
+    }
+    void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
+        m_listeners.push_back( factory );
+    }
+
+    IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
+        return m_factories;
+    }
+    IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
+        return m_listeners;
+    }
+
+}
+// end catch_reporter_registry.cpp
+// start catch_result_type.cpp
+
+namespace Catch {
+
+    bool isOk( ResultWas::OfType resultType ) {
+        return ( resultType & ResultWas::FailureBit ) == 0;
+    }
+    bool isJustInfo( int flags ) {
+        return flags == ResultWas::Info;
+    }
+
+    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+    }
+
+    bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+    bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+// end catch_result_type.cpp
+// start catch_run_context.cpp
+
+#include <cassert>
+#include <algorithm>
+#include <sstream>
+
+namespace Catch {
+
+    namespace Generators {
+        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
+            GeneratorBasePtr m_generator;
+
+            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+            :   TrackerBase( nameAndLocation, ctx, parent )
+            {}
+            ~GeneratorTracker();
+
+            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
+                std::shared_ptr<GeneratorTracker> tracker;
+
+                ITracker& currentTracker = ctx.currentTracker();
+                // Under specific circumstances, the generator we want
+                // to acquire is also the current tracker. If this is
+                // the case, we have to avoid looking through current
+                // tracker's children, and instead return the current
+                // tracker.
+                // A case where this check is important is e.g.
+                //     for (int i = 0; i < 5; ++i) {
+                //         int n = GENERATE(1, 2);
+                //     }
+                //
+                // without it, the code above creates 5 nested generators.
+                if (currentTracker.nameAndLocation() == nameAndLocation) {
+                    auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
+                    assert(thisTracker);
+                    assert(thisTracker->isGeneratorTracker());
+                    tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
+                } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+                    assert( childTracker );
+                    assert( childTracker->isGeneratorTracker() );
+                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
+                } else {
+                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
+                    currentTracker.addChild( tracker );
+                }
+
+                if( !tracker->isComplete() ) {
+                    tracker->open();
+                }
+
+                return *tracker;
+            }
+
+            // TrackerBase interface
+            bool isGeneratorTracker() const override { return true; }
+            auto hasGenerator() const -> bool override {
+                return !!m_generator;
+            }
+            void close() override {
+                TrackerBase::close();
+                // If a generator has a child (it is followed by a section)
+                // and none of its children have started, then we must wait
+                // until later to start consuming its values.
+                // This catches cases where `GENERATE` is placed between two
+                // `SECTION`s.
+                // **The check for m_children.empty cannot be removed**.
+                // doing so would break `GENERATE` _not_ followed by `SECTION`s.
+                const bool should_wait_for_child = [&]() {
+                    // No children -> nobody to wait for
+                    if ( m_children.empty() ) {
+                        return false;
+                    }
+                    // If at least one child started executing, don't wait
+                    if ( std::find_if(
+                             m_children.begin(),
+                             m_children.end(),
+                             []( TestCaseTracking::ITrackerPtr tracker ) {
+                                 return tracker->hasStarted();
+                             } ) != m_children.end() ) {
+                        return false;
+                    }
+
+                    // No children have started. We need to check if they _can_
+                    // start, and thus we should wait for them, or they cannot
+                    // start (due to filters), and we shouldn't wait for them
+                    auto* parent = m_parent;
+                    // This is safe: there is always at least one section
+                    // tracker in a test case tracking tree
+                    while ( !parent->isSectionTracker() ) {
+                        parent = &( parent->parent() );
+                    }
+                    assert( parent &&
+                            "Missing root (test case) level section" );
+
+                    auto const& parentSection =
+                        static_cast<SectionTracker&>( *parent );
+                    auto const& filters = parentSection.getFilters();
+                    // No filters -> no restrictions on running sections
+                    if ( filters.empty() ) {
+                        return true;
+                    }
+
+                    for ( auto const& child : m_children ) {
+                        if ( child->isSectionTracker() &&
+                             std::find( filters.begin(),
+                                        filters.end(),
+                                        static_cast<SectionTracker&>( *child )
+                                            .trimmedName() ) !=
+                                 filters.end() ) {
+                            return true;
+                        }
+                    }
+                    return false;
+                }();
+
+                // This check is a bit tricky, because m_generator->next()
+                // has a side-effect, where it consumes generator's current
+                // value, but we do not want to invoke the side-effect if
+                // this generator is still waiting for any child to start.
+                if ( should_wait_for_child ||
+                     ( m_runState == CompletedSuccessfully &&
+                       m_generator->next() ) ) {
+                    m_children.clear();
+                    m_runState = Executing;
+                }
+            }
+
+            // IGeneratorTracker interface
+            auto getGenerator() const -> GeneratorBasePtr const& override {
+                return m_generator;
+            }
+            void setGenerator( GeneratorBasePtr&& generator ) override {
+                m_generator = std::move( generator );
+            }
+        };
+        GeneratorTracker::~GeneratorTracker() {}
+    }
+
+    RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
+    :   m_runInfo(_config->name()),
+        m_context(getCurrentMutableContext()),
+        m_config(_config),
+        m_reporter(std::move(reporter)),
+        m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
+        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
+    {
+        m_context.setRunner(this);
+        m_context.setConfig(m_config);
+        m_context.setResultCapture(this);
+        m_reporter->testRunStarting(m_runInfo);
+    }
+
+    RunContext::~RunContext() {
+        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
+    }
+
+    void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
+        m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
+    }
+
+    void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
+        m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
+    }
+
+    Totals RunContext::runTest(TestCase const& testCase) {
+        Totals prevTotals = m_totals;
+
+        std::string redirectedCout;
+        std::string redirectedCerr;
+
+        auto const& testInfo = testCase.getTestCaseInfo();
+
+        m_reporter->testCaseStarting(testInfo);
+
+        m_activeTestCase = &testCase;
+
+        ITracker& rootTracker = m_trackerContext.startRun();
+        assert(rootTracker.isSectionTracker());
+        static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
+        do {
+            m_trackerContext.startCycle();
+            m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
+            runCurrentTest(redirectedCout, redirectedCerr);
+        } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
+
+        Totals deltaTotals = m_totals.delta(prevTotals);
+        if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
+            deltaTotals.assertions.failed++;
+            deltaTotals.testCases.passed--;
+            deltaTotals.testCases.failed++;
+        }
+        m_totals.testCases += deltaTotals.testCases;
+        m_reporter->testCaseEnded(TestCaseStats(testInfo,
+                                  deltaTotals,
+                                  redirectedCout,
+                                  redirectedCerr,
+                                  aborting()));
+
+        m_activeTestCase = nullptr;
+        m_testCaseTracker = nullptr;
+
+        return deltaTotals;
+    }
+
+    IConfigPtr RunContext::config() const {
+        return m_config;
+    }
+
+    IStreamingReporter& RunContext::reporter() const {
+        return *m_reporter;
+    }
+
+    void RunContext::assertionEnded(AssertionResult const & result) {
+        if (result.getResultType() == ResultWas::Ok) {
+            m_totals.assertions.passed++;
+            m_lastAssertionPassed = true;
+        } else if (!result.isOk()) {
+            m_lastAssertionPassed = false;
+            if( m_activeTestCase->getTestCaseInfo().okToFail() )
+                m_totals.assertions.failedButOk++;
+            else
+                m_totals.assertions.failed++;
+        }
+        else {
+            m_lastAssertionPassed = true;
+        }
+
+        // We have no use for the return value (whether messages should be cleared), because messages were made scoped
+        // and should be let to clear themselves out.
+        static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
+
+        if (result.getResultType() != ResultWas::Warning)
+            m_messageScopes.clear();
+
+        // Reset working state
+        resetAssertionInfo();
+        m_lastResult = result;
+    }
+    void RunContext::resetAssertionInfo() {
+        m_lastAssertionInfo.macroName = StringRef();
+        m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
+    }
+
+    bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
+        ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
+        if (!sectionTracker.isOpen())
+            return false;
+        m_activeSections.push_back(&sectionTracker);
+
+        m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+        m_reporter->sectionStarting(sectionInfo);
+
+        assertions = m_totals.assertions;
+
+        return true;
+    }
+    auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        using namespace Generators;
+        GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
+                                                              TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
+        m_lastAssertionInfo.lineInfo = lineInfo;
+        return tracker;
+    }
+
+    bool RunContext::testForMissingAssertions(Counts& assertions) {
+        if (assertions.total() != 0)
+            return false;
+        if (!m_config->warnAboutMissingAssertions())
+            return false;
+        if (m_trackerContext.currentTracker().hasChildren())
+            return false;
+        m_totals.assertions.failed++;
+        assertions.failed++;
+        return true;
+    }
+
+    void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
+        Counts assertions = m_totals.assertions - endInfo.prevAssertions;
+        bool missingAssertions = testForMissingAssertions(assertions);
+
+        if (!m_activeSections.empty()) {
+            m_activeSections.back()->close();
+            m_activeSections.pop_back();
+        }
+
+        m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
+        m_messages.clear();
+        m_messageScopes.clear();
+    }
+
+    void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
+        if (m_unfinishedSections.empty())
+            m_activeSections.back()->fail();
+        else
+            m_activeSections.back()->close();
+        m_activeSections.pop_back();
+
+        m_unfinishedSections.push_back(endInfo);
+    }
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void RunContext::benchmarkPreparing(std::string const& name) {
+        m_reporter->benchmarkPreparing(name);
+    }
+    void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
+        m_reporter->benchmarkStarting( info );
+    }
+    void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
+        m_reporter->benchmarkEnded( stats );
+    }
+    void RunContext::benchmarkFailed(std::string const & error) {
+        m_reporter->benchmarkFailed(error);
+    }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+    void RunContext::pushScopedMessage(MessageInfo const & message) {
+        m_messages.push_back(message);
+    }
+
+    void RunContext::popScopedMessage(MessageInfo const & message) {
+        m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
+    }
+
+    void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
+        m_messageScopes.emplace_back( builder );
+    }
+
+    std::string RunContext::getCurrentTestName() const {
+        return m_activeTestCase
+            ? m_activeTestCase->getTestCaseInfo().name
+            : std::string();
+    }
+
+    const AssertionResult * RunContext::getLastResult() const {
+        return &(*m_lastResult);
+    }
+
+    void RunContext::exceptionEarlyReported() {
+        m_shouldReportUnexpected = false;
+    }
+
+    void RunContext::handleFatalErrorCondition( StringRef message ) {
+        // First notify reporter that bad things happened
+        m_reporter->fatalErrorEncountered(message);
+
+        // Don't rebuild the result -- the stringification itself can cause more fatal errors
+        // Instead, fake a result data.
+        AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
+        tempResult.message = static_cast<std::string>(message);
+        AssertionResult result(m_lastAssertionInfo, tempResult);
+
+        assertionEnded(result);
+
+        handleUnfinishedSections();
+
+        // Recreate section for test case (as we will lose the one that was in scope)
+        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
+
+        Counts assertions;
+        assertions.failed = 1;
+        SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
+        m_reporter->sectionEnded(testCaseSectionStats);
+
+        auto const& testInfo = m_activeTestCase->getTestCaseInfo();
+
+        Totals deltaTotals;
+        deltaTotals.testCases.failed = 1;
+        deltaTotals.assertions.failed = 1;
+        m_reporter->testCaseEnded(TestCaseStats(testInfo,
+                                  deltaTotals,
+                                  std::string(),
+                                  std::string(),
+                                  false));
+        m_totals.testCases.failed++;
+        testGroupEnded(std::string(), m_totals, 1, 1);
+        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
+    }
+
+    bool RunContext::lastAssertionPassed() {
+         return m_lastAssertionPassed;
+    }
+
+    void RunContext::assertionPassed() {
+        m_lastAssertionPassed = true;
+        ++m_totals.assertions.passed;
+        resetAssertionInfo();
+        m_messageScopes.clear();
+    }
+
+    bool RunContext::aborting() const {
+        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
+    }
+
+    void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
+        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
+        m_reporter->sectionStarting(testCaseSection);
+        Counts prevAssertions = m_totals.assertions;
+        double duration = 0;
+        m_shouldReportUnexpected = true;
+        m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
+
+        seedRng(*m_config);
+
+        Timer timer;
+        CATCH_TRY {
+            if (m_reporter->getPreferences().shouldRedirectStdOut) {
+#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
+                RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
+
+                timer.start();
+                invokeActiveTestCase();
+#else
+                OutputRedirect r(redirectedCout, redirectedCerr);
+                timer.start();
+                invokeActiveTestCase();
+#endif
+            } else {
+                timer.start();
+                invokeActiveTestCase();
+            }
+            duration = timer.getElapsedSeconds();
+        } CATCH_CATCH_ANON (TestFailureException&) {
+            // This just means the test was aborted due to failure
+        } CATCH_CATCH_ALL {
+            // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
+            // are reported without translation at the point of origin.
+            if( m_shouldReportUnexpected ) {
+                AssertionReaction dummyReaction;
+                handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
+            }
+        }
+        Counts assertions = m_totals.assertions - prevAssertions;
+        bool missingAssertions = testForMissingAssertions(assertions);
+
+        m_testCaseTracker->close();
+        handleUnfinishedSections();
+        m_messages.clear();
+        m_messageScopes.clear();
+
+        SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
+        m_reporter->sectionEnded(testCaseSectionStats);
+    }
+
+    void RunContext::invokeActiveTestCase() {
+        FatalConditionHandlerGuard _(&m_fatalConditionhandler);
+        m_activeTestCase->invoke();
+    }
+
+    void RunContext::handleUnfinishedSections() {
+        // If sections ended prematurely due to an exception we stored their
+        // infos here so we can tear them down outside the unwind process.
+        for (auto it = m_unfinishedSections.rbegin(),
+             itEnd = m_unfinishedSections.rend();
+             it != itEnd;
+             ++it)
+            sectionEnded(*it);
+        m_unfinishedSections.clear();
+    }
+
+    void RunContext::handleExpr(
+        AssertionInfo const& info,
+        ITransientExpression const& expr,
+        AssertionReaction& reaction
+    ) {
+        m_reporter->assertionStarting( info );
+
+        bool negated = isFalseTest( info.resultDisposition );
+        bool result = expr.getResult() != negated;
+
+        if( result ) {
+            if (!m_includeSuccessfulResults) {
+                assertionPassed();
+            }
+            else {
+                reportExpr(info, ResultWas::Ok, &expr, negated);
+            }
+        }
+        else {
+            reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
+            populateReaction( reaction );
+        }
+    }
+    void RunContext::reportExpr(
+            AssertionInfo const &info,
+            ResultWas::OfType resultType,
+            ITransientExpression const *expr,
+            bool negated ) {
+
+        m_lastAssertionInfo = info;
+        AssertionResultData data( resultType, LazyExpression( negated ) );
+
+        AssertionResult assertionResult{ info, data };
+        assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
+
+        assertionEnded( assertionResult );
+    }
+
+    void RunContext::handleMessage(
+            AssertionInfo const& info,
+            ResultWas::OfType resultType,
+            StringRef const& message,
+            AssertionReaction& reaction
+    ) {
+        m_reporter->assertionStarting( info );
+
+        m_lastAssertionInfo = info;
+
+        AssertionResultData data( resultType, LazyExpression( false ) );
+        data.message = static_cast<std::string>(message);
+        AssertionResult assertionResult{ m_lastAssertionInfo, data };
+        assertionEnded( assertionResult );
+        if( !assertionResult.isOk() )
+            populateReaction( reaction );
+    }
+    void RunContext::handleUnexpectedExceptionNotThrown(
+            AssertionInfo const& info,
+            AssertionReaction& reaction
+    ) {
+        handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
+    }
+
+    void RunContext::handleUnexpectedInflightException(
+            AssertionInfo const& info,
+            std::string const& message,
+            AssertionReaction& reaction
+    ) {
+        m_lastAssertionInfo = info;
+
+        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
+        data.message = message;
+        AssertionResult assertionResult{ info, data };
+        assertionEnded( assertionResult );
+        populateReaction( reaction );
+    }
+
+    void RunContext::populateReaction( AssertionReaction& reaction ) {
+        reaction.shouldDebugBreak = m_config->shouldDebugBreak();
+        reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
+    }
+
+    void RunContext::handleIncomplete(
+            AssertionInfo const& info
+    ) {
+        m_lastAssertionInfo = info;
+
+        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
+        data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
+        AssertionResult assertionResult{ info, data };
+        assertionEnded( assertionResult );
+    }
+    void RunContext::handleNonExpr(
+            AssertionInfo const &info,
+            ResultWas::OfType resultType,
+            AssertionReaction &reaction
+    ) {
+        m_lastAssertionInfo = info;
+
+        AssertionResultData data( resultType, LazyExpression( false ) );
+        AssertionResult assertionResult{ info, data };
+        assertionEnded( assertionResult );
+
+        if( !assertionResult.isOk() )
+            populateReaction( reaction );
+    }
+
+    IResultCapture& getResultCapture() {
+        if (auto* capture = getCurrentContext().getResultCapture())
+            return *capture;
+        else
+            CATCH_INTERNAL_ERROR("No result capture instance");
+    }
+
+    void seedRng(IConfig const& config) {
+        if (config.rngSeed() != 0) {
+            std::srand(config.rngSeed());
+            rng().seed(config.rngSeed());
+        }
+    }
+
+    unsigned int rngSeed() {
+        return getCurrentContext().getConfig()->rngSeed();
+    }
+
+}
+// end catch_run_context.cpp
+// start catch_section.cpp
+
+namespace Catch {
+
+    Section::Section( SectionInfo const& info )
+    :   m_info( info ),
+        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+    {
+        m_timer.start();
+    }
+
+    Section::~Section() {
+        if( m_sectionIncluded ) {
+            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
+            if( uncaught_exceptions() )
+                getResultCapture().sectionEndedEarly( endInfo );
+            else
+                getResultCapture().sectionEnded( endInfo );
+        }
+    }
+
+    // This indicates whether the section should be executed or not
+    Section::operator bool() const {
+        return m_sectionIncluded;
+    }
+
+} // end namespace Catch
+// end catch_section.cpp
+// start catch_section_info.cpp
+
+namespace Catch {
+
+    SectionInfo::SectionInfo
+        (   SourceLineInfo const& _lineInfo,
+            std::string const& _name )
+    :   name( _name ),
+        lineInfo( _lineInfo )
+    {}
+
+} // end namespace Catch
+// end catch_section_info.cpp
+// start catch_session.cpp
+
+// start catch_session.h
+
+#include <memory>
+
+namespace Catch {
+
+    class Session : NonCopyable {
+    public:
+
+        Session();
+        ~Session() override;
+
+        void showHelp() const;
+        void libIdentify();
+
+        int applyCommandLine( int argc, char const * const * argv );
+    #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
+        int applyCommandLine( int argc, wchar_t const * const * argv );
+    #endif
+
+        void useConfigData( ConfigData const& configData );
+
+        template<typename CharT>
+        int run(int argc, CharT const * const argv[]) {
+            if (m_startupExceptions)
+                return 1;
+            int returnCode = applyCommandLine(argc, argv);
+            if (returnCode == 0)
+                returnCode = run();
+            return returnCode;
+        }
+
+        int run();
+
+        clara::Parser const& cli() const;
+        void cli( clara::Parser const& newParser );
+        ConfigData& configData();
+        Config& config();
+    private:
+        int runInternal();
+
+        clara::Parser m_cli;
+        ConfigData m_configData;
+        std::shared_ptr<Config> m_config;
+        bool m_startupExceptions = false;
+    };
+
+} // end namespace Catch
+
+// end catch_session.h
+// start catch_version.h
+
+#include <iosfwd>
+
+namespace Catch {
+
+    // Versioning information
+    struct Version {
+        Version( Version const& ) = delete;
+        Version& operator=( Version const& ) = delete;
+        Version(    unsigned int _majorVersion,
+                    unsigned int _minorVersion,
+                    unsigned int _patchNumber,
+                    char const * const _branchName,
+                    unsigned int _buildNumber );
+
+        unsigned int const majorVersion;
+        unsigned int const minorVersion;
+        unsigned int const patchNumber;
+
+        // buildNumber is only used if branchName is not null
+        char const * const branchName;
+        unsigned int const buildNumber;
+
+        friend std::ostream& operator << ( std::ostream& os, Version const& version );
+    };
+
+    Version const& libraryVersion();
+}
+
+// end catch_version.h
+#include <cstdlib>
+#include <iomanip>
+#include <set>
+#include <iterator>
+
+namespace Catch {
+
+    namespace {
+        const int MaxExitCode = 255;
+
+        IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
+            auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
+            CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
+
+            return reporter;
+        }
+
+        IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
+            if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
+                return createReporter(config->getReporterName(), config);
+            }
+
+            // On older platforms, returning std::unique_ptr<ListeningReporter>
+            // when the return type is std::unique_ptr<IStreamingReporter>
+            // doesn't compile without a std::move call. However, this causes
+            // a warning on newer platforms. Thus, we have to work around
+            // it a bit and downcast the pointer manually.
+            auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
+            auto& multi = static_cast<ListeningReporter&>(*ret);
+            auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
+            for (auto const& listener : listeners) {
+                multi.addListener(listener->create(Catch::ReporterConfig(config)));
+            }
+            multi.addReporter(createReporter(config->getReporterName(), config));
+            return ret;
+        }
+
+        class TestGroup {
+        public:
+            explicit TestGroup(std::shared_ptr<Config> const& config)
+            : m_config{config}
+            , m_context{config, makeReporter(config)}
+            {
+                auto const& allTestCases = getAllTestCasesSorted(*m_config);
+                m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
+                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
+
+                if (m_matches.empty() && invalidArgs.empty()) {
+                    for (auto const& test : allTestCases)
+                        if (!test.isHidden())
+                            m_tests.emplace(&test);
+                } else {
+                    for (auto const& match : m_matches)
+                        m_tests.insert(match.tests.begin(), match.tests.end());
+                }
+            }
+
+            Totals execute() {
+                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
+                Totals totals;
+                m_context.testGroupStarting(m_config->name(), 1, 1);
+                for (auto const& testCase : m_tests) {
+                    if (!m_context.aborting())
+                        totals += m_context.runTest(*testCase);
+                    else
+                        m_context.reporter().skipTest(*testCase);
+                }
+
+                for (auto const& match : m_matches) {
+                    if (match.tests.empty()) {
+                        m_context.reporter().noMatchingTestCases(match.name);
+                        totals.error = -1;
+                    }
+                }
+
+                if (!invalidArgs.empty()) {
+                    for (auto const& invalidArg: invalidArgs)
+                         m_context.reporter().reportInvalidArguments(invalidArg);
+                }
+
+                m_context.testGroupEnded(m_config->name(), totals, 1, 1);
+                return totals;
+            }
+
+        private:
+            using Tests = std::set<TestCase const*>;
+
+            std::shared_ptr<Config> m_config;
+            RunContext m_context;
+            Tests m_tests;
+            TestSpec::Matches m_matches;
+        };
+
+        void applyFilenamesAsTags(Catch::IConfig const& config) {
+            auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
+            for (auto& testCase : tests) {
+                auto tags = testCase.tags;
+
+                std::string filename = testCase.lineInfo.file;
+                auto lastSlash = filename.find_last_of("\\/");
+                if (lastSlash != std::string::npos) {
+                    filename.erase(0, lastSlash);
+                    filename[0] = '#';
+                }
+                else
+                {
+                    filename.insert(0, "#");
+                }
+
+                auto lastDot = filename.find_last_of('.');
+                if (lastDot != std::string::npos) {
+                    filename.erase(lastDot);
+                }
+
+                tags.push_back(std::move(filename));
+                setTags(testCase, tags);
+            }
+        }
+
+    } // anon namespace
+
+    Session::Session() {
+        static bool alreadyInstantiated = false;
+        if( alreadyInstantiated ) {
+            CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
+            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
+        }
+
+        // There cannot be exceptions at startup in no-exception mode.
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+        const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
+        if ( !exceptions.empty() ) {
+            config();
+            getCurrentMutableContext().setConfig(m_config);
+
+            m_startupExceptions = true;
+            Colour colourGuard( Colour::Red );
+            Catch::cerr() << "Errors occurred during startup!" << '\n';
+            // iterate over all exceptions and notify user
+            for ( const auto& ex_ptr : exceptions ) {
+                try {
+                    std::rethrow_exception(ex_ptr);
+                } catch ( std::exception const& ex ) {
+                    Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
+                }
+            }
+        }
+#endif
+
+        alreadyInstantiated = true;
+        m_cli = makeCommandLineParser( m_configData );
+    }
+    Session::~Session() {
+        Catch::cleanUp();
+    }
+
+    void Session::showHelp() const {
+        Catch::cout()
+                << "\nCatch v" << libraryVersion() << "\n"
+                << m_cli << std::endl
+                << "For more detailed usage please see the project docs\n" << std::endl;
+    }
+    void Session::libIdentify() {
+        Catch::cout()
+                << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
+                << std::left << std::setw(16) << "category: " << "testframework\n"
+                << std::left << std::setw(16) << "framework: " << "Catch Test\n"
+                << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
+    }
+
+    int Session::applyCommandLine( int argc, char const * const * argv ) {
+        if( m_startupExceptions )
+            return 1;
+
+        auto result = m_cli.parse( clara::Args( argc, argv ) );
+        if( !result ) {
+            config();
+            getCurrentMutableContext().setConfig(m_config);
+            Catch::cerr()
+                << Colour( Colour::Red )
+                << "\nError(s) in input:\n"
+                << Column( result.errorMessage() ).indent( 2 )
+                << "\n\n";
+            Catch::cerr() << "Run with -? for usage\n" << std::endl;
+            return MaxExitCode;
+        }
+
+        if( m_configData.showHelp )
+            showHelp();
+        if( m_configData.libIdentify )
+            libIdentify();
+        m_config.reset();
+        return 0;
+    }
+
+#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
+    int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
+
+        char **utf8Argv = new char *[ argc ];
+
+        for ( int i = 0; i < argc; ++i ) {
+            int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
+
+            utf8Argv[ i ] = new char[ bufSize ];
+
+            WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
+        }
+
+        int returnCode = applyCommandLine( argc, utf8Argv );
+
+        for ( int i = 0; i < argc; ++i )
+            delete [] utf8Argv[ i ];
+
+        delete [] utf8Argv;
+
+        return returnCode;
+    }
+#endif
+
+    void Session::useConfigData( ConfigData const& configData ) {
+        m_configData = configData;
+        m_config.reset();
+    }
+
+    int Session::run() {
+        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
+            Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
+            static_cast<void>(std::getchar());
+        }
+        int exitCode = runInternal();
+        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
+            Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
+            static_cast<void>(std::getchar());
+        }
+        return exitCode;
+    }
+
+    clara::Parser const& Session::cli() const {
+        return m_cli;
+    }
+    void Session::cli( clara::Parser const& newParser ) {
+        m_cli = newParser;
+    }
+    ConfigData& Session::configData() {
+        return m_configData;
+    }
+    Config& Session::config() {
+        if( !m_config )
+            m_config = std::make_shared<Config>( m_configData );
+        return *m_config;
+    }
+
+    int Session::runInternal() {
+        if( m_startupExceptions )
+            return 1;
+
+        if (m_configData.showHelp || m_configData.libIdentify) {
+            return 0;
+        }
+
+        CATCH_TRY {
+            config(); // Force config to be constructed
+
+            seedRng( *m_config );
+
+            if( m_configData.filenamesAsTags )
+                applyFilenamesAsTags( *m_config );
+
+            // Handle list request
+            if( Option<std::size_t> listed = list( m_config ) )
+                return static_cast<int>( *listed );
+
+            TestGroup tests { m_config };
+            auto const totals = tests.execute();
+
+            if( m_config->warnAboutNoTests() && totals.error == -1 )
+                return 2;
+
+            // Note that on unices only the lower 8 bits are usually used, clamping
+            // the return value to 255 prevents false negative when some multiple
+            // of 256 tests has failed
+            return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
+        }
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+        catch( std::exception& ex ) {
+            Catch::cerr() << ex.what() << std::endl;
+            return MaxExitCode;
+        }
+#endif
+    }
+
+} // end namespace Catch
+// end catch_session.cpp
+// start catch_singletons.cpp
+
+#include <vector>
+
+namespace Catch {
+
+    namespace {
+        static auto getSingletons() -> std::vector<ISingleton*>*& {
+            static std::vector<ISingleton*>* g_singletons = nullptr;
+            if( !g_singletons )
+                g_singletons = new std::vector<ISingleton*>();
+            return g_singletons;
+        }
+    }
+
+    ISingleton::~ISingleton() {}
+
+    void addSingleton(ISingleton* singleton ) {
+        getSingletons()->push_back( singleton );
+    }
+    void cleanupSingletons() {
+        auto& singletons = getSingletons();
+        for( auto singleton : *singletons )
+            delete singleton;
+        delete singletons;
+        singletons = nullptr;
+    }
+
+} // namespace Catch
+// end catch_singletons.cpp
+// start catch_startup_exception_registry.cpp
+
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+namespace Catch {
+void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
+        CATCH_TRY {
+            m_exceptions.push_back(exception);
+        } CATCH_CATCH_ALL {
+            // If we run out of memory during start-up there's really not a lot more we can do about it
+            std::terminate();
+        }
+    }
+
+    std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
+        return m_exceptions;
+    }
+
+} // end namespace Catch
+#endif
+// end catch_startup_exception_registry.cpp
+// start catch_stream.cpp
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+    Catch::IStream::~IStream() = default;
+
+    namespace Detail { namespace {
+        template<typename WriterF, std::size_t bufferSize=256>
+        class StreamBufImpl : public std::streambuf {
+            char data[bufferSize];
+            WriterF m_writer;
+
+        public:
+            StreamBufImpl() {
+                setp( data, data + sizeof(data) );
+            }
+
+            ~StreamBufImpl() noexcept {
+                StreamBufImpl::sync();
+            }
+
+        private:
+            int overflow( int c ) override {
+                sync();
+
+                if( c != EOF ) {
+                    if( pbase() == epptr() )
+                        m_writer( std::string( 1, static_cast<char>( c ) ) );
+                    else
+                        sputc( static_cast<char>( c ) );
+                }
+                return 0;
+            }
+
+            int sync() override {
+                if( pbase() != pptr() ) {
+                    m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+                    setp( pbase(), epptr() );
+                }
+                return 0;
+            }
+        };
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        struct OutputDebugWriter {
+
+            void operator()( std::string const&str ) {
+                writeToDebugConsole( str );
+            }
+        };
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        class FileStream : public IStream {
+            mutable std::ofstream m_ofs;
+        public:
+            FileStream( StringRef filename ) {
+                m_ofs.open( filename.c_str() );
+                CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
+            }
+            ~FileStream() override = default;
+        public: // IStream
+            std::ostream& stream() const override {
+                return m_ofs;
+            }
+        };
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        class CoutStream : public IStream {
+            mutable std::ostream m_os;
+        public:
+            // Store the streambuf from cout up-front because
+            // cout may get redirected when running tests
+            CoutStream() : m_os( Catch::cout().rdbuf() ) {}
+            ~CoutStream() override = default;
+
+        public: // IStream
+            std::ostream& stream() const override { return m_os; }
+        };
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        class DebugOutStream : public IStream {
+            std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
+            mutable std::ostream m_os;
+        public:
+            DebugOutStream()
+            :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+                m_os( m_streamBuf.get() )
+            {}
+
+            ~DebugOutStream() override = default;
+
+        public: // IStream
+            std::ostream& stream() const override { return m_os; }
+        };
+
+    }} // namespace anon::detail
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    auto makeStream( StringRef const &filename ) -> IStream const* {
+        if( filename.empty() )
+            return new Detail::CoutStream();
+        else if( filename[0] == '%' ) {
+            if( filename == "%debug" )
+                return new Detail::DebugOutStream();
+            else
+                CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
+        }
+        else
+            return new Detail::FileStream( filename );
+    }
+
+    // This class encapsulates the idea of a pool of ostringstreams that can be reused.
+    struct StringStreams {
+        std::vector<std::unique_ptr<std::ostringstream>> m_streams;
+        std::vector<std::size_t> m_unused;
+        std::ostringstream m_referenceStream; // Used for copy state/ flags from
+
+        auto add() -> std::size_t {
+            if( m_unused.empty() ) {
+                m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
+                return m_streams.size()-1;
+            }
+            else {
+                auto index = m_unused.back();
+                m_unused.pop_back();
+                return index;
+            }
+        }
+
+        void release( std::size_t index ) {
+            m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
+            m_unused.push_back(index);
+        }
+    };
+
+    ReusableStringStream::ReusableStringStream()
+    :   m_index( Singleton<StringStreams>::getMutable().add() ),
+        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
+    {}
+
+    ReusableStringStream::~ReusableStringStream() {
+        static_cast<std::ostringstream*>( m_oss )->str("");
+        m_oss->clear();
+        Singleton<StringStreams>::getMutable().release( m_index );
+    }
+
+    auto ReusableStringStream::str() const -> std::string {
+        return static_cast<std::ostringstream*>( m_oss )->str();
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
+    std::ostream& cout() { return std::cout; }
+    std::ostream& cerr() { return std::cerr; }
+    std::ostream& clog() { return std::clog; }
+#endif
+}
+// end catch_stream.cpp
+// start catch_string_manip.cpp
+
+#include <algorithm>
+#include <ostream>
+#include <cstring>
+#include <cctype>
+#include <vector>
+
+namespace Catch {
+
+    namespace {
+        char toLowerCh(char c) {
+            return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
+        }
+    }
+
+    bool startsWith( std::string const& s, std::string const& prefix ) {
+        return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
+    }
+    bool startsWith( std::string const& s, char prefix ) {
+        return !s.empty() && s[0] == prefix;
+    }
+    bool endsWith( std::string const& s, std::string const& suffix ) {
+        return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
+    }
+    bool endsWith( std::string const& s, char suffix ) {
+        return !s.empty() && s[s.size()-1] == suffix;
+    }
+    bool contains( std::string const& s, std::string const& infix ) {
+        return s.find( infix ) != std::string::npos;
+    }
+    void toLowerInPlace( std::string& s ) {
+        std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
+    }
+    std::string toLower( std::string const& s ) {
+        std::string lc = s;
+        toLowerInPlace( lc );
+        return lc;
+    }
+    std::string trim( std::string const& str ) {
+        static char const* whitespaceChars = "\n\r\t ";
+        std::string::size_type start = str.find_first_not_of( whitespaceChars );
+        std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+        return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
+    }
+
+    StringRef trim(StringRef ref) {
+        const auto is_ws = [](char c) {
+            return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+        };
+        size_t real_begin = 0;
+        while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
+        size_t real_end = ref.size();
+        while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
+
+        return ref.substr(real_begin, real_end - real_begin);
+    }
+
+    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+        bool replaced = false;
+        std::size_t i = str.find( replaceThis );
+        while( i != std::string::npos ) {
+            replaced = true;
+            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+            if( i < str.size()-withThis.size() )
+                i = str.find( replaceThis, i+withThis.size() );
+            else
+                i = std::string::npos;
+        }
+        return replaced;
+    }
+
+    std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
+        std::vector<StringRef> subStrings;
+        std::size_t start = 0;
+        for(std::size_t pos = 0; pos < str.size(); ++pos ) {
+            if( str[pos] == delimiter ) {
+                if( pos - start > 1 )
+                    subStrings.push_back( str.substr( start, pos-start ) );
+                start = pos+1;
+            }
+        }
+        if( start < str.size() )
+            subStrings.push_back( str.substr( start, str.size()-start ) );
+        return subStrings;
+    }
+
+    pluralise::pluralise( std::size_t count, std::string const& label )
+    :   m_count( count ),
+        m_label( label )
+    {}
+
+    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+        os << pluraliser.m_count << ' ' << pluraliser.m_label;
+        if( pluraliser.m_count != 1 )
+            os << 's';
+        return os;
+    }
+
+}
+// end catch_string_manip.cpp
+// start catch_stringref.cpp
+
+#include <algorithm>
+#include <ostream>
+#include <cstring>
+#include <cstdint>
+
+namespace Catch {
+    StringRef::StringRef( char const* rawChars ) noexcept
+    : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
+    {}
+
+    auto StringRef::c_str() const -> char const* {
+        CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
+        return m_start;
+    }
+    auto StringRef::data() const noexcept -> char const* {
+        return m_start;
+    }
+
+    auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
+        if (start < m_size) {
+            return StringRef(m_start + start, (std::min)(m_size - start, size));
+        } else {
+            return StringRef();
+        }
+    }
+    auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
+        return m_size == other.m_size
+            && (std::memcmp( m_start, other.m_start, m_size ) == 0);
+    }
+
+    auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
+        return os.write(str.data(), str.size());
+    }
+
+    auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
+        lhs.append(rhs.data(), rhs.size());
+        return lhs;
+    }
+
+} // namespace Catch
+// end catch_stringref.cpp
+// start catch_tag_alias.cpp
+
+namespace Catch {
+    TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
+}
+// end catch_tag_alias.cpp
+// start catch_tag_alias_autoregistrar.cpp
+
+namespace Catch {
+
+    RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
+        CATCH_TRY {
+            getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
+        } CATCH_CATCH_ALL {
+            // Do not throw when constructing global objects, instead register the exception to be processed later
+            getMutableRegistryHub().registerStartupException();
+        }
+    }
+
+}
+// end catch_tag_alias_autoregistrar.cpp
+// start catch_tag_alias_registry.cpp
+
+#include <sstream>
+
+namespace Catch {
+
+    TagAliasRegistry::~TagAliasRegistry() {}
+
+    TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
+        auto it = m_registry.find( alias );
+        if( it != m_registry.end() )
+            return &(it->second);
+        else
+            return nullptr;
+    }
+
+    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+        std::string expandedTestSpec = unexpandedTestSpec;
+        for( auto const& registryKvp : m_registry ) {
+            std::size_t pos = expandedTestSpec.find( registryKvp.first );
+            if( pos != std::string::npos ) {
+                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
+                                    registryKvp.second.tag +
+                                    expandedTestSpec.substr( pos + registryKvp.first.size() );
+            }
+        }
+        return expandedTestSpec;
+    }
+
+    void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
+        CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
+                      "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
+
+        CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
+                      "error: tag alias, '" << alias << "' already registered.\n"
+                      << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
+                      << "\tRedefined at: " << lineInfo );
+    }
+
+    ITagAliasRegistry::~ITagAliasRegistry() {}
+
+    ITagAliasRegistry const& ITagAliasRegistry::get() {
+        return getRegistryHub().getTagAliasRegistry();
+    }
+
+} // end namespace Catch
+// end catch_tag_alias_registry.cpp
+// start catch_test_case_info.cpp
+
+#include <cctype>
+#include <exception>
+#include <algorithm>
+#include <sstream>
+
+namespace Catch {
+
+    namespace {
+        TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+            if( startsWith( tag, '.' ) ||
+                tag == "!hide" )
+                return TestCaseInfo::IsHidden;
+            else if( tag == "!throws" )
+                return TestCaseInfo::Throws;
+            else if( tag == "!shouldfail" )
+                return TestCaseInfo::ShouldFail;
+            else if( tag == "!mayfail" )
+                return TestCaseInfo::MayFail;
+            else if( tag == "!nonportable" )
+                return TestCaseInfo::NonPortable;
+            else if( tag == "!benchmark" )
+                return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
+            else
+                return TestCaseInfo::None;
+        }
+        bool isReservedTag( std::string const& tag ) {
+            return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
+        }
+        void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+            CATCH_ENFORCE( !isReservedTag(tag),
+                          "Tag name: [" << tag << "] is not allowed.\n"
+                          << "Tag names starting with non alphanumeric characters are reserved\n"
+                          << _lineInfo );
+        }
+    }
+
+    TestCase makeTestCase(  ITestInvoker* _testCase,
+                            std::string const& _className,
+                            NameAndTags const& nameAndTags,
+                            SourceLineInfo const& _lineInfo )
+    {
+        bool isHidden = false;
+
+        // Parse out tags
+        std::vector<std::string> tags;
+        std::string desc, tag;
+        bool inTag = false;
+        for (char c : nameAndTags.tags) {
+            if( !inTag ) {
+                if( c == '[' )
+                    inTag = true;
+                else
+                    desc += c;
+            }
+            else {
+                if( c == ']' ) {
+                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+                    if( ( prop & TestCaseInfo::IsHidden ) != 0 )
+                        isHidden = true;
+                    else if( prop == TestCaseInfo::None )
+                        enforceNotReservedTag( tag, _lineInfo );
+
+                    // Merged hide tags like `[.approvals]` should be added as
+                    // `[.][approvals]`. The `[.]` is added at later point, so
+                    // we only strip the prefix
+                    if (startsWith(tag, '.') && tag.size() > 1) {
+                        tag.erase(0, 1);
+                    }
+                    tags.push_back( tag );
+                    tag.clear();
+                    inTag = false;
+                }
+                else
+                    tag += c;
+            }
+        }
+        if( isHidden ) {
+            // Add all "hidden" tags to make them behave identically
+            tags.insert( tags.end(), { ".", "!hide" } );
+        }
+
+        TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
+        return TestCase( _testCase, std::move(info) );
+    }
+
+    void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
+        std::sort(begin(tags), end(tags));
+        tags.erase(std::unique(begin(tags), end(tags)), end(tags));
+        testCaseInfo.lcaseTags.clear();
+
+        for( auto const& tag : tags ) {
+            std::string lcaseTag = toLower( tag );
+            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
+            testCaseInfo.lcaseTags.push_back( lcaseTag );
+        }
+        testCaseInfo.tags = std::move(tags);
+    }
+
+    TestCaseInfo::TestCaseInfo( std::string const& _name,
+                                std::string const& _className,
+                                std::string const& _description,
+                                std::vector<std::string> const& _tags,
+                                SourceLineInfo const& _lineInfo )
+    :   name( _name ),
+        className( _className ),
+        description( _description ),
+        lineInfo( _lineInfo ),
+        properties( None )
+    {
+        setTags( *this, _tags );
+    }
+
+    bool TestCaseInfo::isHidden() const {
+        return ( properties & IsHidden ) != 0;
+    }
+    bool TestCaseInfo::throws() const {
+        return ( properties & Throws ) != 0;
+    }
+    bool TestCaseInfo::okToFail() const {
+        return ( properties & (ShouldFail | MayFail ) ) != 0;
+    }
+    bool TestCaseInfo::expectedToFail() const {
+        return ( properties & (ShouldFail ) ) != 0;
+    }
+
+    std::string TestCaseInfo::tagsAsString() const {
+        std::string ret;
+        // '[' and ']' per tag
+        std::size_t full_size = 2 * tags.size();
+        for (const auto& tag : tags) {
+            full_size += tag.size();
+        }
+        ret.reserve(full_size);
+        for (const auto& tag : tags) {
+            ret.push_back('[');
+            ret.append(tag);
+            ret.push_back(']');
+        }
+
+        return ret;
+    }
+
+    TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
+
+    TestCase TestCase::withName( std::string const& _newName ) const {
+        TestCase other( *this );
+        other.name = _newName;
+        return other;
+    }
+
+    void TestCase::invoke() const {
+        test->invoke();
+    }
+
+    bool TestCase::operator == ( TestCase const& other ) const {
+        return  test.get() == other.test.get() &&
+                name == other.name &&
+                className == other.className;
+    }
+
+    bool TestCase::operator < ( TestCase const& other ) const {
+        return name < other.name;
+    }
+
+    TestCaseInfo const& TestCase::getTestCaseInfo() const
+    {
+        return *this;
+    }
+
+} // end namespace Catch
+// end catch_test_case_info.cpp
+// start catch_test_case_registry_impl.cpp
+
+#include <algorithm>
+#include <sstream>
+
+namespace Catch {
+
+    namespace {
+        struct TestHasher {
+            using hash_t = uint64_t;
+
+            explicit TestHasher( hash_t hashSuffix ):
+                m_hashSuffix{ hashSuffix } {}
+
+            uint32_t operator()( TestCase const& t ) const {
+                // FNV-1a hash with multiplication fold.
+                const hash_t prime = 1099511628211u;
+                hash_t hash = 14695981039346656037u;
+                for ( const char c : t.name ) {
+                    hash ^= c;
+                    hash *= prime;
+                }
+                hash ^= m_hashSuffix;
+                hash *= prime;
+                const uint32_t low{ static_cast<uint32_t>( hash ) };
+                const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };
+                return low * high;
+            }
+
+        private:
+            hash_t m_hashSuffix;
+        };
+    } // end unnamed namespace
+
+    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
+        switch( config.runOrder() ) {
+            case RunTests::InDeclarationOrder:
+                // already in declaration order
+                break;
+
+            case RunTests::InLexicographicalOrder: {
+                std::vector<TestCase> sorted = unsortedTestCases;
+                std::sort( sorted.begin(), sorted.end() );
+                return sorted;
+            }
+
+            case RunTests::InRandomOrder: {
+                seedRng( config );
+                TestHasher h{ config.rngSeed() };
+
+                using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;
+                std::vector<hashedTest> indexed_tests;
+                indexed_tests.reserve( unsortedTestCases.size() );
+
+                for (auto const& testCase : unsortedTestCases) {
+                    indexed_tests.emplace_back(h(testCase), &testCase);
+                }
+
+                std::sort(indexed_tests.begin(), indexed_tests.end(),
+                          [](hashedTest const& lhs, hashedTest const& rhs) {
+                          if (lhs.first == rhs.first) {
+                              return lhs.second->name < rhs.second->name;
+                          }
+                          return lhs.first < rhs.first;
+                });
+
+                std::vector<TestCase> sorted;
+                sorted.reserve( indexed_tests.size() );
+
+                for (auto const& hashed : indexed_tests) {
+                    sorted.emplace_back(*hashed.second);
+                }
+
+                return sorted;
+            }
+        }
+        return unsortedTestCases;
+    }
+
+    bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
+        return !testCase.throws() || config.allowThrows();
+    }
+
+    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
+        return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
+    }
+
+    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
+        std::set<TestCase> seenFunctions;
+        for( auto const& function : functions ) {
+            auto prev = seenFunctions.insert( function );
+            CATCH_ENFORCE( prev.second,
+                    "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
+                    << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
+                    << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
+        }
+    }
+
+    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
+        std::vector<TestCase> filtered;
+        filtered.reserve( testCases.size() );
+        for (auto const& testCase : testCases) {
+            if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
+                (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
+                filtered.push_back(testCase);
+            }
+        }
+        return filtered;
+    }
+    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
+        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
+    }
+
+    void TestRegistry::registerTest( TestCase const& testCase ) {
+        std::string name = testCase.getTestCaseInfo().name;
+        if( name.empty() ) {
+            ReusableStringStream rss;
+            rss << "Anonymous test case " << ++m_unnamedCount;
+            return registerTest( testCase.withName( rss.str() ) );
+        }
+        m_functions.push_back( testCase );
+    }
+
+    std::vector<TestCase> const& TestRegistry::getAllTests() const {
+        return m_functions;
+    }
+    std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
+        if( m_sortedFunctions.empty() )
+            enforceNoDuplicateTestCases( m_functions );
+
+        if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
+            m_sortedFunctions = sortTests( config, m_functions );
+            m_currentSortOrder = config.runOrder();
+        }
+        return m_sortedFunctions;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
+
+    void TestInvokerAsFunction::invoke() const {
+        m_testAsFunction();
+    }
+
+    std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
+        std::string className(classOrQualifiedMethodName);
+        if( startsWith( className, '&' ) )
+        {
+            std::size_t lastColons = className.rfind( "::" );
+            std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+            if( penultimateColons == std::string::npos )
+                penultimateColons = 1;
+            className = className.substr( penultimateColons, lastColons-penultimateColons );
+        }
+        return className;
+    }
+
+} // end namespace Catch
+// end catch_test_case_registry_impl.cpp
+// start catch_test_case_tracker.cpp
+
+#include <algorithm>
+#include <cassert>
+#include <stdexcept>
+#include <memory>
+#include <sstream>
+
+#if defined(__clang__)
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+namespace Catch {
+namespace TestCaseTracking {
+
+    NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
+    :   name( _name ),
+        location( _location )
+    {}
+
+    ITracker::~ITracker() = default;
+
+    ITracker& TrackerContext::startRun() {
+        m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
+        m_currentTracker = nullptr;
+        m_runState = Executing;
+        return *m_rootTracker;
+    }
+
+    void TrackerContext::endRun() {
+        m_rootTracker.reset();
+        m_currentTracker = nullptr;
+        m_runState = NotStarted;
+    }
+
+    void TrackerContext::startCycle() {
+        m_currentTracker = m_rootTracker.get();
+        m_runState = Executing;
+    }
+    void TrackerContext::completeCycle() {
+        m_runState = CompletedCycle;
+    }
+
+    bool TrackerContext::completedCycle() const {
+        return m_runState == CompletedCycle;
+    }
+    ITracker& TrackerContext::currentTracker() {
+        return *m_currentTracker;
+    }
+    void TrackerContext::setCurrentTracker( ITracker* tracker ) {
+        m_currentTracker = tracker;
+    }
+
+    TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
+        ITracker(nameAndLocation),
+        m_ctx( ctx ),
+        m_parent( parent )
+    {}
+
+    bool TrackerBase::isComplete() const {
+        return m_runState == CompletedSuccessfully || m_runState == Failed;
+    }
+    bool TrackerBase::isSuccessfullyCompleted() const {
+        return m_runState == CompletedSuccessfully;
+    }
+    bool TrackerBase::isOpen() const {
+        return m_runState != NotStarted && !isComplete();
+    }
+    bool TrackerBase::hasChildren() const {
+        return !m_children.empty();
+    }
+
+    void TrackerBase::addChild( ITrackerPtr const& child ) {
+        m_children.push_back( child );
+    }
+
+    ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
+        auto it = std::find_if( m_children.begin(), m_children.end(),
+            [&nameAndLocation]( ITrackerPtr const& tracker ){
+                return
+                    tracker->nameAndLocation().location == nameAndLocation.location &&
+                    tracker->nameAndLocation().name == nameAndLocation.name;
+            } );
+        return( it != m_children.end() )
+            ? *it
+            : nullptr;
+    }
+    ITracker& TrackerBase::parent() {
+        assert( m_parent ); // Should always be non-null except for root
+        return *m_parent;
+    }
+
+    void TrackerBase::openChild() {
+        if( m_runState != ExecutingChildren ) {
+            m_runState = ExecutingChildren;
+            if( m_parent )
+                m_parent->openChild();
+        }
+    }
+
+    bool TrackerBase::isSectionTracker() const { return false; }
+    bool TrackerBase::isGeneratorTracker() const { return false; }
+
+    void TrackerBase::open() {
+        m_runState = Executing;
+        moveToThis();
+        if( m_parent )
+            m_parent->openChild();
+    }
+
+    void TrackerBase::close() {
+
+        // Close any still open children (e.g. generators)
+        while( &m_ctx.currentTracker() != this )
+            m_ctx.currentTracker().close();
+
+        switch( m_runState ) {
+            case NeedsAnotherRun:
+                break;
+
+            case Executing:
+                m_runState = CompletedSuccessfully;
+                break;
+            case ExecutingChildren:
+                if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
+                    m_runState = CompletedSuccessfully;
+                break;
+
+            case NotStarted:
+            case CompletedSuccessfully:
+            case Failed:
+                CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
+
+            default:
+                CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
+        }
+        moveToParent();
+        m_ctx.completeCycle();
+    }
+    void TrackerBase::fail() {
+        m_runState = Failed;
+        if( m_parent )
+            m_parent->markAsNeedingAnotherRun();
+        moveToParent();
+        m_ctx.completeCycle();
+    }
+    void TrackerBase::markAsNeedingAnotherRun() {
+        m_runState = NeedsAnotherRun;
+    }
+
+    void TrackerBase::moveToParent() {
+        assert( m_parent );
+        m_ctx.setCurrentTracker( m_parent );
+    }
+    void TrackerBase::moveToThis() {
+        m_ctx.setCurrentTracker( this );
+    }
+
+    SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+    :   TrackerBase( nameAndLocation, ctx, parent ),
+        m_trimmed_name(trim(nameAndLocation.name))
+    {
+        if( parent ) {
+            while( !parent->isSectionTracker() )
+                parent = &parent->parent();
+
+            SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
+            addNextFilters( parentSection.m_filters );
+        }
+    }
+
+    bool SectionTracker::isComplete() const {
+        bool complete = true;
+
+        if (m_filters.empty()
+            || m_filters[0] == ""
+            || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
+            complete = TrackerBase::isComplete();
+        }
+        return complete;
+    }
+
+    bool SectionTracker::isSectionTracker() const { return true; }
+
+    SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
+        std::shared_ptr<SectionTracker> section;
+
+        ITracker& currentTracker = ctx.currentTracker();
+        if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+            assert( childTracker );
+            assert( childTracker->isSectionTracker() );
+            section = std::static_pointer_cast<SectionTracker>( childTracker );
+        }
+        else {
+            section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
+            currentTracker.addChild( section );
+        }
+        if( !ctx.completedCycle() )
+            section->tryOpen();
+        return *section;
+    }
+
+    void SectionTracker::tryOpen() {
+        if( !isComplete() )
+            open();
+    }
+
+    void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
+        if( !filters.empty() ) {
+            m_filters.reserve( m_filters.size() + filters.size() + 2 );
+            m_filters.emplace_back(""); // Root - should never be consulted
+            m_filters.emplace_back(""); // Test Case - not a section filter
+            m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
+        }
+    }
+    void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
+        if( filters.size() > 1 )
+            m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
+    }
+
+    std::vector<std::string> const& SectionTracker::getFilters() const {
+        return m_filters;
+    }
+
+    std::string const& SectionTracker::trimmedName() const {
+        return m_trimmed_name;
+    }
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+
+} // namespace Catch
+
+#if defined(__clang__)
+#    pragma clang diagnostic pop
+#endif
+// end catch_test_case_tracker.cpp
+// start catch_test_registry.cpp
+
+namespace Catch {
+
+    auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
+        return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
+    }
+
+    NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
+
+    AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
+        CATCH_TRY {
+            getMutableRegistryHub()
+                    .registerTest(
+                        makeTestCase(
+                            invoker,
+                            extractClassName( classOrMethod ),
+                            nameAndTags,
+                            lineInfo));
+        } CATCH_CATCH_ALL {
+            // Do not throw when constructing global objects, instead register the exception to be processed later
+            getMutableRegistryHub().registerStartupException();
+        }
+    }
+
+    AutoReg::~AutoReg() = default;
+}
+// end catch_test_registry.cpp
+// start catch_test_spec.cpp
+
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace Catch {
+
+    TestSpec::Pattern::Pattern( std::string const& name )
+    : m_name( name )
+    {}
+
+    TestSpec::Pattern::~Pattern() = default;
+
+    std::string const& TestSpec::Pattern::name() const {
+        return m_name;
+    }
+
+    TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
+    : Pattern( filterString )
+    , m_wildcardPattern( toLower( name ), CaseSensitive::No )
+    {}
+
+    bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
+        return m_wildcardPattern.matches( testCase.name );
+    }
+
+    TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
+    : Pattern( filterString )
+    , m_tag( toLower( tag ) )
+    {}
+
+    bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
+        return std::find(begin(testCase.lcaseTags),
+                         end(testCase.lcaseTags),
+                         m_tag) != end(testCase.lcaseTags);
+    }
+
+    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
+    : Pattern( underlyingPattern->name() )
+    , m_underlyingPattern( underlyingPattern )
+    {}
+
+    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
+        return !m_underlyingPattern->matches( testCase );
+    }
+
+    bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
+        return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
+    }
+
+    std::string TestSpec::Filter::name() const {
+        std::string name;
+        for( auto const& p : m_patterns )
+            name += p->name();
+        return name;
+    }
+
+    bool TestSpec::hasFilters() const {
+        return !m_filters.empty();
+    }
+
+    bool TestSpec::matches( TestCaseInfo const& testCase ) const {
+        return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
+    }
+
+    TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
+    {
+        Matches matches( m_filters.size() );
+        std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
+            std::vector<TestCase const*> currentMatches;
+            for( auto const& test : testCases )
+                if( isThrowSafe( test, config ) && filter.matches( test ) )
+                    currentMatches.emplace_back( &test );
+            return FilterMatch{ filter.name(), currentMatches };
+        } );
+        return matches;
+    }
+
+    const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
+        return  (m_invalidArgs);
+    }
+
+}
+// end catch_test_spec.cpp
+// start catch_test_spec_parser.cpp
+
+namespace Catch {
+
+    TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+    TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
+        m_mode = None;
+        m_exclusion = false;
+        m_arg = m_tagAliases->expandAliases( arg );
+        m_escapeChars.clear();
+        m_substring.reserve(m_arg.size());
+        m_patternName.reserve(m_arg.size());
+        m_realPatternPos = 0;
+
+        for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+          //if visitChar fails
+           if( !visitChar( m_arg[m_pos] ) ){
+               m_testSpec.m_invalidArgs.push_back(arg);
+               break;
+           }
+        endMode();
+        return *this;
+    }
+    TestSpec TestSpecParser::testSpec() {
+        addFilter();
+        return m_testSpec;
+    }
+    bool TestSpecParser::visitChar( char c ) {
+        if( (m_mode != EscapedName) && (c == '\\') ) {
+            escape();
+            addCharToPattern(c);
+            return true;
+        }else if((m_mode != EscapedName) && (c == ',') )  {
+            return separate();
+        }
+
+        switch( m_mode ) {
+        case None:
+            if( processNoneChar( c ) )
+                return true;
+            break;
+        case Name:
+            processNameChar( c );
+            break;
+        case EscapedName:
+            endMode();
+            addCharToPattern(c);
+            return true;
+        default:
+        case Tag:
+        case QuotedName:
+            if( processOtherChar( c ) )
+                return true;
+            break;
+        }
+
+        m_substring += c;
+        if( !isControlChar( c ) ) {
+            m_patternName += c;
+            m_realPatternPos++;
+        }
+        return true;
+    }
+    // Two of the processing methods return true to signal the caller to return
+    // without adding the given character to the current pattern strings
+    bool TestSpecParser::processNoneChar( char c ) {
+        switch( c ) {
+        case ' ':
+            return true;
+        case '~':
+            m_exclusion = true;
+            return false;
+        case '[':
+            startNewMode( Tag );
+            return false;
+        case '"':
+            startNewMode( QuotedName );
+            return false;
+        default:
+            startNewMode( Name );
+            return false;
+        }
+    }
+    void TestSpecParser::processNameChar( char c ) {
+        if( c == '[' ) {
+            if( m_substring == "exclude:" )
+                m_exclusion = true;
+            else
+                endMode();
+            startNewMode( Tag );
+        }
+    }
+    bool TestSpecParser::processOtherChar( char c ) {
+        if( !isControlChar( c ) )
+            return false;
+        m_substring += c;
+        endMode();
+        return true;
+    }
+    void TestSpecParser::startNewMode( Mode mode ) {
+        m_mode = mode;
+    }
+    void TestSpecParser::endMode() {
+        switch( m_mode ) {
+        case Name:
+        case QuotedName:
+            return addNamePattern();
+        case Tag:
+            return addTagPattern();
+        case EscapedName:
+            revertBackToLastMode();
+            return;
+        case None:
+        default:
+            return startNewMode( None );
+        }
+    }
+    void TestSpecParser::escape() {
+        saveLastMode();
+        m_mode = EscapedName;
+        m_escapeChars.push_back(m_realPatternPos);
+    }
+    bool TestSpecParser::isControlChar( char c ) const {
+        switch( m_mode ) {
+            default:
+                return false;
+            case None:
+                return c == '~';
+            case Name:
+                return c == '[';
+            case EscapedName:
+                return true;
+            case QuotedName:
+                return c == '"';
+            case Tag:
+                return c == '[' || c == ']';
+        }
+    }
+
+    void TestSpecParser::addFilter() {
+        if( !m_currentFilter.m_patterns.empty() ) {
+            m_testSpec.m_filters.push_back( m_currentFilter );
+            m_currentFilter = TestSpec::Filter();
+        }
+    }
+
+    void TestSpecParser::saveLastMode() {
+      lastMode = m_mode;
+    }
+
+    void TestSpecParser::revertBackToLastMode() {
+      m_mode = lastMode;
+    }
+
+    bool TestSpecParser::separate() {
+      if( (m_mode==QuotedName) || (m_mode==Tag) ){
+         //invalid argument, signal failure to previous scope.
+         m_mode = None;
+         m_pos = m_arg.size();
+         m_substring.clear();
+         m_patternName.clear();
+         m_realPatternPos = 0;
+         return false;
+      }
+      endMode();
+      addFilter();
+      return true; //success
+    }
+
+    std::string TestSpecParser::preprocessPattern() {
+        std::string token = m_patternName;
+        for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
+            token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
+        m_escapeChars.clear();
+        if (startsWith(token, "exclude:")) {
+            m_exclusion = true;
+            token = token.substr(8);
+        }
+
+        m_patternName.clear();
+        m_realPatternPos = 0;
+
+        return token;
+    }
+
+    void TestSpecParser::addNamePattern() {
+        auto token = preprocessPattern();
+
+        if (!token.empty()) {
+            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
+            if (m_exclusion)
+                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+            m_currentFilter.m_patterns.push_back(pattern);
+        }
+        m_substring.clear();
+        m_exclusion = false;
+        m_mode = None;
+    }
+
+    void TestSpecParser::addTagPattern() {
+        auto token = preprocessPattern();
+
+        if (!token.empty()) {
+            // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
+            // we have to create a separate hide tag and shorten the real one
+            if (token.size() > 1 && token[0] == '.') {
+                token.erase(token.begin());
+                TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
+                if (m_exclusion) {
+                    pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+                }
+                m_currentFilter.m_patterns.push_back(pattern);
+            }
+
+            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
+
+            if (m_exclusion) {
+                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+            }
+            m_currentFilter.m_patterns.push_back(pattern);
+        }
+        m_substring.clear();
+        m_exclusion = false;
+        m_mode = None;
+    }
+
+    TestSpec parseTestSpec( std::string const& arg ) {
+        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+    }
+
+} // namespace Catch
+// end catch_test_spec_parser.cpp
+// start catch_timer.cpp
+
+#include <chrono>
+
+static const uint64_t nanosecondsInSecond = 1000000000;
+
+namespace Catch {
+
+    auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
+        return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
+    }
+
+    namespace {
+        auto estimateClockResolution() -> uint64_t {
+            uint64_t sum = 0;
+            static const uint64_t iterations = 1000000;
+
+            auto startTime = getCurrentNanosecondsSinceEpoch();
+
+            for( std::size_t i = 0; i < iterations; ++i ) {
+
+                uint64_t ticks;
+                uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
+                do {
+                    ticks = getCurrentNanosecondsSinceEpoch();
+                } while( ticks == baseTicks );
+
+                auto delta = ticks - baseTicks;
+                sum += delta;
+
+                // If we have been calibrating for over 3 seconds -- the clock
+                // is terrible and we should move on.
+                // TBD: How to signal that the measured resolution is probably wrong?
+                if (ticks > startTime + 3 * nanosecondsInSecond) {
+                    return sum / ( i + 1u );
+                }
+            }
+
+            // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
+            // - and potentially do more iterations if there's a high variance.
+            return sum/iterations;
+        }
+    }
+    auto getEstimatedClockResolution() -> uint64_t {
+        static auto s_resolution = estimateClockResolution();
+        return s_resolution;
+    }
+
+    void Timer::start() {
+       m_nanoseconds = getCurrentNanosecondsSinceEpoch();
+    }
+    auto Timer::getElapsedNanoseconds() const -> uint64_t {
+        return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
+    }
+    auto Timer::getElapsedMicroseconds() const -> uint64_t {
+        return getElapsedNanoseconds()/1000;
+    }
+    auto Timer::getElapsedMilliseconds() const -> unsigned int {
+        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+    }
+    auto Timer::getElapsedSeconds() const -> double {
+        return getElapsedMicroseconds()/1000000.0;
+    }
+
+} // namespace Catch
+// end catch_timer.cpp
+// start catch_tostring.cpp
+
+#if defined(__clang__)
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wexit-time-destructors"
+#    pragma clang diagnostic ignored "-Wglobal-constructors"
+#endif
+
+// Enable specific decls locally
+#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#endif
+
+#include <cmath>
+#include <iomanip>
+
+namespace Catch {
+
+namespace Detail {
+
+    const std::string unprintableString = "{?}";
+
+    namespace {
+        const int hexThreshold = 255;
+
+        struct Endianness {
+            enum Arch { Big, Little };
+
+            static Arch which() {
+                int one = 1;
+                // If the lowest byte we read is non-zero, we can assume
+                // that little endian format is used.
+                auto value = *reinterpret_cast<char*>(&one);
+                return value ? Little : Big;
+            }
+        };
+    }
+
+    std::string rawMemoryToString( const void *object, std::size_t size ) {
+        // Reverse order for little endian architectures
+        int i = 0, end = static_cast<int>( size ), inc = 1;
+        if( Endianness::which() == Endianness::Little ) {
+            i = end-1;
+            end = inc = -1;
+        }
+
+        unsigned char const *bytes = static_cast<unsigned char const *>(object);
+        ReusableStringStream rss;
+        rss << "0x" << std::setfill('0') << std::hex;
+        for( ; i != end; i += inc )
+             rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
+       return rss.str();
+    }
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+    if (Catch::isnan(value)) {
+        return "nan";
+    }
+
+    ReusableStringStream rss;
+    rss << std::setprecision( precision )
+        << std::fixed
+        << value;
+    std::string d = rss.str();
+    std::size_t i = d.find_last_not_of( '0' );
+    if( i != std::string::npos && i != d.size()-1 ) {
+        if( d[i] == '.' )
+            i++;
+        d = d.substr( 0, i+1 );
+    }
+    return d;
+}
+
+//// ======================================================= ////
+//
+//   Out-of-line defs for full specialization of StringMaker
+//
+//// ======================================================= ////
+
+std::string StringMaker<std::string>::convert(const std::string& str) {
+    if (!getCurrentContext().getConfig()->showInvisibles()) {
+        return '"' + str + '"';
+    }
+
+    std::string s("\"");
+    for (char c : str) {
+        switch (c) {
+        case '\n':
+            s.append("\\n");
+            break;
+        case '\t':
+            s.append("\\t");
+            break;
+        default:
+            s.push_back(c);
+            break;
+        }
+    }
+    s.append("\"");
+    return s;
+}
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::string_view>::convert(std::string_view str) {
+    return ::Catch::Detail::stringify(std::string{ str });
+}
+#endif
+
+std::string StringMaker<char const*>::convert(char const* str) {
+    if (str) {
+        return ::Catch::Detail::stringify(std::string{ str });
+    } else {
+        return{ "{null string}" };
+    }
+}
+std::string StringMaker<char*>::convert(char* str) {
+    if (str) {
+        return ::Catch::Detail::stringify(std::string{ str });
+    } else {
+        return{ "{null string}" };
+    }
+}
+
+#ifdef CATCH_CONFIG_WCHAR
+std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
+    std::string s;
+    s.reserve(wstr.size());
+    for (auto c : wstr) {
+        s += (c <= 0xff) ? static_cast<char>(c) : '?';
+    }
+    return ::Catch::Detail::stringify(s);
+}
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
+    return StringMaker<std::wstring>::convert(std::wstring(str));
+}
+# endif
+
+std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
+    if (str) {
+        return ::Catch::Detail::stringify(std::wstring{ str });
+    } else {
+        return{ "{null string}" };
+    }
+}
+std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
+    if (str) {
+        return ::Catch::Detail::stringify(std::wstring{ str });
+    } else {
+        return{ "{null string}" };
+    }
+}
+#endif
+
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+#include <cstddef>
+std::string StringMaker<std::byte>::convert(std::byte value) {
+    return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
+}
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
+
+std::string StringMaker<int>::convert(int value) {
+    return ::Catch::Detail::stringify(static_cast<long long>(value));
+}
+std::string StringMaker<long>::convert(long value) {
+    return ::Catch::Detail::stringify(static_cast<long long>(value));
+}
+std::string StringMaker<long long>::convert(long long value) {
+    ReusableStringStream rss;
+    rss << value;
+    if (value > Detail::hexThreshold) {
+        rss << " (0x" << std::hex << value << ')';
+    }
+    return rss.str();
+}
+
+std::string StringMaker<unsigned int>::convert(unsigned int value) {
+    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
+}
+std::string StringMaker<unsigned long>::convert(unsigned long value) {
+    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
+}
+std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
+    ReusableStringStream rss;
+    rss << value;
+    if (value > Detail::hexThreshold) {
+        rss << " (0x" << std::hex << value << ')';
+    }
+    return rss.str();
+}
+
+std::string StringMaker<bool>::convert(bool b) {
+    return b ? "true" : "false";
+}
+
+std::string StringMaker<signed char>::convert(signed char value) {
+    if (value == '\r') {
+        return "'\\r'";
+    } else if (value == '\f') {
+        return "'\\f'";
+    } else if (value == '\n') {
+        return "'\\n'";
+    } else if (value == '\t') {
+        return "'\\t'";
+    } else if ('\0' <= value && value < ' ') {
+        return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
+    } else {
+        char chstr[] = "' '";
+        chstr[1] = value;
+        return chstr;
+    }
+}
+std::string StringMaker<char>::convert(char c) {
+    return ::Catch::Detail::stringify(static_cast<signed char>(c));
+}
+std::string StringMaker<unsigned char>::convert(unsigned char c) {
+    return ::Catch::Detail::stringify(static_cast<char>(c));
+}
+
+std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
+    return "nullptr";
+}
+
+int StringMaker<float>::precision = 5;
+
+std::string StringMaker<float>::convert(float value) {
+    return fpToString(value, precision) + 'f';
+}
+
+int StringMaker<double>::precision = 10;
+
+std::string StringMaker<double>::convert(double value) {
+    return fpToString(value, precision);
+}
+
+std::string ratio_string<std::atto>::symbol() { return "a"; }
+std::string ratio_string<std::femto>::symbol() { return "f"; }
+std::string ratio_string<std::pico>::symbol() { return "p"; }
+std::string ratio_string<std::nano>::symbol() { return "n"; }
+std::string ratio_string<std::micro>::symbol() { return "u"; }
+std::string ratio_string<std::milli>::symbol() { return "m"; }
+
+} // end namespace Catch
+
+#if defined(__clang__)
+#    pragma clang diagnostic pop
+#endif
+
+// end catch_tostring.cpp
+// start catch_totals.cpp
+
+namespace Catch {
+
+    Counts Counts::operator - ( Counts const& other ) const {
+        Counts diff;
+        diff.passed = passed - other.passed;
+        diff.failed = failed - other.failed;
+        diff.failedButOk = failedButOk - other.failedButOk;
+        return diff;
+    }
+
+    Counts& Counts::operator += ( Counts const& other ) {
+        passed += other.passed;
+        failed += other.failed;
+        failedButOk += other.failedButOk;
+        return *this;
+    }
+
+    std::size_t Counts::total() const {
+        return passed + failed + failedButOk;
+    }
+    bool Counts::allPassed() const {
+        return failed == 0 && failedButOk == 0;
+    }
+    bool Counts::allOk() const {
+        return failed == 0;
+    }
+
+    Totals Totals::operator - ( Totals const& other ) const {
+        Totals diff;
+        diff.assertions = assertions - other.assertions;
+        diff.testCases = testCases - other.testCases;
+        return diff;
+    }
+
+    Totals& Totals::operator += ( Totals const& other ) {
+        assertions += other.assertions;
+        testCases += other.testCases;
+        return *this;
+    }
+
+    Totals Totals::delta( Totals const& prevTotals ) const {
+        Totals diff = *this - prevTotals;
+        if( diff.assertions.failed > 0 )
+            ++diff.testCases.failed;
+        else if( diff.assertions.failedButOk > 0 )
+            ++diff.testCases.failedButOk;
+        else
+            ++diff.testCases.passed;
+        return diff;
+    }
+
+}
+// end catch_totals.cpp
+// start catch_uncaught_exceptions.cpp
+
+// start catch_config_uncaught_exceptions.hpp
+
+//              Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+//   (See accompanying file LICENSE_1_0.txt or copy at
+//        https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+
+#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+
+#if defined(_MSC_VER)
+#  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
+#    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#  endif
+#endif
+
+#include <exception>
+
+#if defined(__cpp_lib_uncaught_exceptions) \
+    && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+
+#  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif // __cpp_lib_uncaught_exceptions
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
+    && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
+    && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+
+#  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif
+
+#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+// end catch_config_uncaught_exceptions.hpp
+#include <exception>
+
+namespace Catch {
+    bool uncaught_exceptions() {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+        return false;
+#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+        return std::uncaught_exceptions() > 0;
+#else
+        return std::uncaught_exception();
+#endif
+  }
+} // end namespace Catch
+// end catch_uncaught_exceptions.cpp
+// start catch_version.cpp
+
+#include <ostream>
+
+namespace Catch {
+
+    Version::Version
+        (   unsigned int _majorVersion,
+            unsigned int _minorVersion,
+            unsigned int _patchNumber,
+            char const * const _branchName,
+            unsigned int _buildNumber )
+    :   majorVersion( _majorVersion ),
+        minorVersion( _minorVersion ),
+        patchNumber( _patchNumber ),
+        branchName( _branchName ),
+        buildNumber( _buildNumber )
+    {}
+
+    std::ostream& operator << ( std::ostream& os, Version const& version ) {
+        os  << version.majorVersion << '.'
+            << version.minorVersion << '.'
+            << version.patchNumber;
+        // branchName is never null -> 0th char is \0 if it is empty
+        if (version.branchName[0]) {
+            os << '-' << version.branchName
+               << '.' << version.buildNumber;
+        }
+        return os;
+    }
+
+    Version const& libraryVersion() {
+        static Version version( 2, 13, 9, "", 0 );
+        return version;
+    }
+
+}
+// end catch_version.cpp
+// start catch_wildcard_pattern.cpp
+
+namespace Catch {
+
+    WildcardPattern::WildcardPattern( std::string const& pattern,
+                                      CaseSensitive::Choice caseSensitivity )
+    :   m_caseSensitivity( caseSensitivity ),
+        m_pattern( normaliseString( pattern ) )
+    {
+        if( startsWith( m_pattern, '*' ) ) {
+            m_pattern = m_pattern.substr( 1 );
+            m_wildcard = WildcardAtStart;
+        }
+        if( endsWith( m_pattern, '*' ) ) {
+            m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
+            m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+        }
+    }
+
+    bool WildcardPattern::matches( std::string const& str ) const {
+        switch( m_wildcard ) {
+            case NoWildcard:
+                return m_pattern == normaliseString( str );
+            case WildcardAtStart:
+                return endsWith( normaliseString( str ), m_pattern );
+            case WildcardAtEnd:
+                return startsWith( normaliseString( str ), m_pattern );
+            case WildcardAtBothEnds:
+                return contains( normaliseString( str ), m_pattern );
+            default:
+                CATCH_INTERNAL_ERROR( "Unknown enum" );
+        }
+    }
+
+    std::string WildcardPattern::normaliseString( std::string const& str ) const {
+        return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
+    }
+}
+// end catch_wildcard_pattern.cpp
+// start catch_xmlwriter.cpp
+
+#include <iomanip>
+#include <type_traits>
+
+namespace Catch {
+
+namespace {
+
+    size_t trailingBytes(unsigned char c) {
+        if ((c & 0xE0) == 0xC0) {
+            return 2;
+        }
+        if ((c & 0xF0) == 0xE0) {
+            return 3;
+        }
+        if ((c & 0xF8) == 0xF0) {
+            return 4;
+        }
+        CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
+    }
+
+    uint32_t headerValue(unsigned char c) {
+        if ((c & 0xE0) == 0xC0) {
+            return c & 0x1F;
+        }
+        if ((c & 0xF0) == 0xE0) {
+            return c & 0x0F;
+        }
+        if ((c & 0xF8) == 0xF0) {
+            return c & 0x07;
+        }
+        CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
+    }
+
+    void hexEscapeChar(std::ostream& os, unsigned char c) {
+        std::ios_base::fmtflags f(os.flags());
+        os << "\\x"
+            << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
+            << static_cast<int>(c);
+        os.flags(f);
+    }
+
+    bool shouldNewline(XmlFormatting fmt) {
+        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
+    }
+
+    bool shouldIndent(XmlFormatting fmt) {
+        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
+    }
+
+} // anonymous namespace
+
+    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
+        return static_cast<XmlFormatting>(
+            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
+            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
+        );
+    }
+
+    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
+        return static_cast<XmlFormatting>(
+            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
+            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
+        );
+    }
+
+    XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
+    :   m_str( str ),
+        m_forWhat( forWhat )
+    {}
+
+    void XmlEncode::encodeTo( std::ostream& os ) const {
+        // Apostrophe escaping not necessary if we always use " to write attributes
+        // (see: http://www.w3.org/TR/xml/#syntax)
+
+        for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
+            unsigned char c = m_str[idx];
+            switch (c) {
+            case '<':   os << "&lt;"; break;
+            case '&':   os << "&amp;"; break;
+
+            case '>':
+                // See: http://www.w3.org/TR/xml/#syntax
+                if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
+                    os << "&gt;";
+                else
+                    os << c;
+                break;
+
+            case '\"':
+                if (m_forWhat == ForAttributes)
+                    os << "&quot;";
+                else
+                    os << c;
+                break;
+
+            default:
+                // Check for control characters and invalid utf-8
+
+                // Escape control characters in standard ascii
+                // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
+                if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
+                    hexEscapeChar(os, c);
+                    break;
+                }
+
+                // Plain ASCII: Write it to stream
+                if (c < 0x7F) {
+                    os << c;
+                    break;
+                }
+
+                // UTF-8 territory
+                // Check if the encoding is valid and if it is not, hex escape bytes.
+                // Important: We do not check the exact decoded values for validity, only the encoding format
+                // First check that this bytes is a valid lead byte:
+                // This means that it is not encoded as 1111 1XXX
+                // Or as 10XX XXXX
+                if (c <  0xC0 ||
+                    c >= 0xF8) {
+                    hexEscapeChar(os, c);
+                    break;
+                }
+
+                auto encBytes = trailingBytes(c);
+                // Are there enough bytes left to avoid accessing out-of-bounds memory?
+                if (idx + encBytes - 1 >= m_str.size()) {
+                    hexEscapeChar(os, c);
+                    break;
+                }
+                // The header is valid, check data
+                // The next encBytes bytes must together be a valid utf-8
+                // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
+                bool valid = true;
+                uint32_t value = headerValue(c);
+                for (std::size_t n = 1; n < encBytes; ++n) {
+                    unsigned char nc = m_str[idx + n];
+                    valid &= ((nc & 0xC0) == 0x80);
+                    value = (value << 6) | (nc & 0x3F);
+                }
+
+                if (
+                    // Wrong bit pattern of following bytes
+                    (!valid) ||
+                    // Overlong encodings
+                    (value < 0x80) ||
+                    (0x80 <= value && value < 0x800   && encBytes > 2) ||
+                    (0x800 < value && value < 0x10000 && encBytes > 3) ||
+                    // Encoded value out of range
+                    (value >= 0x110000)
+                    ) {
+                    hexEscapeChar(os, c);
+                    break;
+                }
+
+                // If we got here, this is in fact a valid(ish) utf-8 sequence
+                for (std::size_t n = 0; n < encBytes; ++n) {
+                    os << m_str[idx + n];
+                }
+                idx += encBytes - 1;
+                break;
+            }
+        }
+    }
+
+    std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
+        xmlEncode.encodeTo( os );
+        return os;
+    }
+
+    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
+    :   m_writer( writer ),
+        m_fmt(fmt)
+    {}
+
+    XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
+    :   m_writer( other.m_writer ),
+        m_fmt(other.m_fmt)
+    {
+        other.m_writer = nullptr;
+        other.m_fmt = XmlFormatting::None;
+    }
+    XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
+        if ( m_writer ) {
+            m_writer->endElement();
+        }
+        m_writer = other.m_writer;
+        other.m_writer = nullptr;
+        m_fmt = other.m_fmt;
+        other.m_fmt = XmlFormatting::None;
+        return *this;
+    }
+
+    XmlWriter::ScopedElement::~ScopedElement() {
+        if (m_writer) {
+            m_writer->endElement(m_fmt);
+        }
+    }
+
+    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
+        m_writer->writeText( text, fmt );
+        return *this;
+    }
+
+    XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
+    {
+        writeDeclaration();
+    }
+
+    XmlWriter::~XmlWriter() {
+        while (!m_tags.empty()) {
+            endElement();
+        }
+        newlineIfNecessary();
+    }
+
+    XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
+        ensureTagClosed();
+        newlineIfNecessary();
+        if (shouldIndent(fmt)) {
+            m_os << m_indent;
+            m_indent += "  ";
+        }
+        m_os << '<' << name;
+        m_tags.push_back( name );
+        m_tagIsOpen = true;
+        applyFormatting(fmt);
+        return *this;
+    }
+
+    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
+        ScopedElement scoped( this, fmt );
+        startElement( name, fmt );
+        return scoped;
+    }
+
+    XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
+        m_indent = m_indent.substr(0, m_indent.size() - 2);
+
+        if( m_tagIsOpen ) {
+            m_os << "/>";
+            m_tagIsOpen = false;
+        } else {
+            newlineIfNecessary();
+            if (shouldIndent(fmt)) {
+                m_os << m_indent;
+            }
+            m_os << "</" << m_tags.back() << ">";
+        }
+        m_os << std::flush;
+        applyFormatting(fmt);
+        m_tags.pop_back();
+        return *this;
+    }
+
+    XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
+        if( !name.empty() && !attribute.empty() )
+            m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
+        return *this;
+    }
+
+    XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
+        m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
+        return *this;
+    }
+
+    XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
+        if( !text.empty() ){
+            bool tagWasOpen = m_tagIsOpen;
+            ensureTagClosed();
+            if (tagWasOpen && shouldIndent(fmt)) {
+                m_os << m_indent;
+            }
+            m_os << XmlEncode( text );
+            applyFormatting(fmt);
+        }
+        return *this;
+    }
+
+    XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
+        ensureTagClosed();
+        if (shouldIndent(fmt)) {
+            m_os << m_indent;
+        }
+        m_os << "<!--" << text << "-->";
+        applyFormatting(fmt);
+        return *this;
+    }
+
+    void XmlWriter::writeStylesheetRef( std::string const& url ) {
+        m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
+    }
+
+    XmlWriter& XmlWriter::writeBlankLine() {
+        ensureTagClosed();
+        m_os << '\n';
+        return *this;
+    }
+
+    void XmlWriter::ensureTagClosed() {
+        if( m_tagIsOpen ) {
+            m_os << '>' << std::flush;
+            newlineIfNecessary();
+            m_tagIsOpen = false;
+        }
+    }
+
+    void XmlWriter::applyFormatting(XmlFormatting fmt) {
+        m_needsNewline = shouldNewline(fmt);
+    }
+
+    void XmlWriter::writeDeclaration() {
+        m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+    }
+
+    void XmlWriter::newlineIfNecessary() {
+        if( m_needsNewline ) {
+            m_os << std::endl;
+            m_needsNewline = false;
+        }
+    }
+}
+// end catch_xmlwriter.cpp
+// start catch_reporter_bases.cpp
+
+#include <cstring>
+#include <cfloat>
+#include <cstdio>
+#include <cassert>
+#include <memory>
+
+namespace Catch {
+    void prepareExpandedExpression(AssertionResult& result) {
+        result.getExpandedExpression();
+    }
+
+    // Because formatting using c++ streams is stateful, drop down to C is required
+    // Alternatively we could use stringstream, but its performance is... not good.
+    std::string getFormattedDuration( double duration ) {
+        // Max exponent + 1 is required to represent the whole part
+        // + 1 for decimal point
+        // + 3 for the 3 decimal places
+        // + 1 for null terminator
+        const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
+        char buffer[maxDoubleSize];
+
+        // Save previous errno, to prevent sprintf from overwriting it
+        ErrnoGuard guard;
+#ifdef _MSC_VER
+        sprintf_s(buffer, "%.3f", duration);
+#else
+        std::sprintf(buffer, "%.3f", duration);
+#endif
+        return std::string(buffer);
+    }
+
+    bool shouldShowDuration( IConfig const& config, double duration ) {
+        if ( config.showDurations() == ShowDurations::Always ) {
+            return true;
+        }
+        if ( config.showDurations() == ShowDurations::Never ) {
+            return false;
+        }
+        const double min = config.minDuration();
+        return min >= 0 && duration >= min;
+    }
+
+    std::string serializeFilters( std::vector<std::string> const& container ) {
+        ReusableStringStream oss;
+        bool first = true;
+        for (auto&& filter : container)
+        {
+            if (!first)
+                oss << ' ';
+            else
+                first = false;
+
+            oss << filter;
+        }
+        return oss.str();
+    }
+
+    TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
+        :StreamingReporterBase(_config) {}
+
+    std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
+        return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
+    }
+
+    void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
+
+    bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
+        return false;
+    }
+
+} // end namespace Catch
+// end catch_reporter_bases.cpp
+// start catch_reporter_compact.cpp
+
+namespace {
+
+#ifdef CATCH_PLATFORM_MAC
+    const char* failedString() { return "FAILED"; }
+    const char* passedString() { return "PASSED"; }
+#else
+    const char* failedString() { return "failed"; }
+    const char* passedString() { return "passed"; }
+#endif
+
+    // Colour::LightGrey
+    Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
+
+    std::string bothOrAll( std::size_t count ) {
+        return count == 1 ? std::string() :
+               count == 2 ? "both " : "all " ;
+    }
+
+} // anon namespace
+
+namespace Catch {
+namespace {
+// Colour, message variants:
+// - white: No tests ran.
+// -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
+// - white: Passed [both/all] N test cases (no assertions).
+// -   red: Failed N tests cases, failed M assertions.
+// - green: Passed [both/all] N tests cases with M assertions.
+void printTotals(std::ostream& out, const Totals& totals) {
+    if (totals.testCases.total() == 0) {
+        out << "No tests ran.";
+    } else if (totals.testCases.failed == totals.testCases.total()) {
+        Colour colour(Colour::ResultError);
+        const std::string qualify_assertions_failed =
+            totals.assertions.failed == totals.assertions.total() ?
+            bothOrAll(totals.assertions.failed) : std::string();
+        out <<
+            "Failed " << bothOrAll(totals.testCases.failed)
+            << pluralise(totals.testCases.failed, "test case") << ", "
+            "failed " << qualify_assertions_failed <<
+            pluralise(totals.assertions.failed, "assertion") << '.';
+    } else if (totals.assertions.total() == 0) {
+        out <<
+            "Passed " << bothOrAll(totals.testCases.total())
+            << pluralise(totals.testCases.total(), "test case")
+            << " (no assertions).";
+    } else if (totals.assertions.failed) {
+        Colour colour(Colour::ResultError);
+        out <<
+            "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
+            "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
+    } else {
+        Colour colour(Colour::ResultSuccess);
+        out <<
+            "Passed " << bothOrAll(totals.testCases.passed)
+            << pluralise(totals.testCases.passed, "test case") <<
+            " with " << pluralise(totals.assertions.passed, "assertion") << '.';
+    }
+}
+
+// Implementation of CompactReporter formatting
+class AssertionPrinter {
+public:
+    AssertionPrinter& operator= (AssertionPrinter const&) = delete;
+    AssertionPrinter(AssertionPrinter const&) = delete;
+    AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
+        : stream(_stream)
+        , result(_stats.assertionResult)
+        , messages(_stats.infoMessages)
+        , itMessage(_stats.infoMessages.begin())
+        , printInfoMessages(_printInfoMessages) {}
+
+    void print() {
+        printSourceInfo();
+
+        itMessage = messages.begin();
+
+        switch (result.getResultType()) {
+        case ResultWas::Ok:
+            printResultType(Colour::ResultSuccess, passedString());
+            printOriginalExpression();
+            printReconstructedExpression();
+            if (!result.hasExpression())
+                printRemainingMessages(Colour::None);
+            else
+                printRemainingMessages();
+            break;
+        case ResultWas::ExpressionFailed:
+            if (result.isOk())
+                printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
+            else
+                printResultType(Colour::Error, failedString());
+            printOriginalExpression();
+            printReconstructedExpression();
+            printRemainingMessages();
+            break;
+        case ResultWas::ThrewException:
+            printResultType(Colour::Error, failedString());
+            printIssue("unexpected exception with message:");
+            printMessage();
+            printExpressionWas();
+            printRemainingMessages();
+            break;
+        case ResultWas::FatalErrorCondition:
+            printResultType(Colour::Error, failedString());
+            printIssue("fatal error condition with message:");
+            printMessage();
+            printExpressionWas();
+            printRemainingMessages();
+            break;
+        case ResultWas::DidntThrowException:
+            printResultType(Colour::Error, failedString());
+            printIssue("expected exception, got none");
+            printExpressionWas();
+            printRemainingMessages();
+            break;
+        case ResultWas::Info:
+            printResultType(Colour::None, "info");
+            printMessage();
+            printRemainingMessages();
+            break;
+        case ResultWas::Warning:
+            printResultType(Colour::None, "warning");
+            printMessage();
+            printRemainingMessages();
+            break;
+        case ResultWas::ExplicitFailure:
+            printResultType(Colour::Error, failedString());
+            printIssue("explicitly");
+            printRemainingMessages(Colour::None);
+            break;
+            // These cases are here to prevent compiler warnings
+        case ResultWas::Unknown:
+        case ResultWas::FailureBit:
+        case ResultWas::Exception:
+            printResultType(Colour::Error, "** internal error **");
+            break;
+        }
+    }
+
+private:
+    void printSourceInfo() const {
+        Colour colourGuard(Colour::FileName);
+        stream << result.getSourceInfo() << ':';
+    }
+
+    void printResultType(Colour::Code colour, std::string const& passOrFail) const {
+        if (!passOrFail.empty()) {
+            {
+                Colour colourGuard(colour);
+                stream << ' ' << passOrFail;
+            }
+            stream << ':';
+        }
+    }
+
+    void printIssue(std::string const& issue) const {
+        stream << ' ' << issue;
+    }
+
+    void printExpressionWas() {
+        if (result.hasExpression()) {
+            stream << ';';
+            {
+                Colour colour(dimColour());
+                stream << " expression was:";
+            }
+            printOriginalExpression();
+        }
+    }
+
+    void printOriginalExpression() const {
+        if (result.hasExpression()) {
+            stream << ' ' << result.getExpression();
+        }
+    }
+
+    void printReconstructedExpression() const {
+        if (result.hasExpandedExpression()) {
+            {
+                Colour colour(dimColour());
+                stream << " for: ";
+            }
+            stream << result.getExpandedExpression();
+        }
+    }
+
+    void printMessage() {
+        if (itMessage != messages.end()) {
+            stream << " '" << itMessage->message << '\'';
+            ++itMessage;
+        }
+    }
+
+    void printRemainingMessages(Colour::Code colour = dimColour()) {
+        if (itMessage == messages.end())
+            return;
+
+        const auto itEnd = messages.cend();
+        const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
+
+        {
+            Colour colourGuard(colour);
+            stream << " with " << pluralise(N, "message") << ':';
+        }
+
+        while (itMessage != itEnd) {
+            // If this assertion is a warning ignore any INFO messages
+            if (printInfoMessages || itMessage->type != ResultWas::Info) {
+                printMessage();
+                if (itMessage != itEnd) {
+                    Colour colourGuard(dimColour());
+                    stream << " and";
+                }
+                continue;
+            }
+            ++itMessage;
+        }
+    }
+
+private:
+    std::ostream& stream;
+    AssertionResult const& result;
+    std::vector<MessageInfo> messages;
+    std::vector<MessageInfo>::const_iterator itMessage;
+    bool printInfoMessages;
+};
+
+} // anon namespace
+
+        std::string CompactReporter::getDescription() {
+            return "Reports test results on a single line, suitable for IDEs";
+        }
+
+        void CompactReporter::noMatchingTestCases( std::string const& spec ) {
+            stream << "No test cases matched '" << spec << '\'' << std::endl;
+        }
+
+        void CompactReporter::assertionStarting( AssertionInfo const& ) {}
+
+        bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
+            AssertionResult const& result = _assertionStats.assertionResult;
+
+            bool printInfoMessages = true;
+
+            // Drop out if result was successful and we're not printing those
+            if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+                if( result.getResultType() != ResultWas::Warning )
+                    return false;
+                printInfoMessages = false;
+            }
+
+            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+            printer.print();
+
+            stream << std::endl;
+            return true;
+        }
+
+        void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
+            double dur = _sectionStats.durationInSeconds;
+            if ( shouldShowDuration( *m_config, dur ) ) {
+                stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+            }
+        }
+
+        void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
+            printTotals( stream, _testRunStats.totals );
+            stream << '\n' << std::endl;
+            StreamingReporterBase::testRunEnded( _testRunStats );
+        }
+
+        CompactReporter::~CompactReporter() {}
+
+    CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+// end catch_reporter_compact.cpp
+// start catch_reporter_console.cpp
+
+#include <cfloat>
+#include <cstdio>
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
+ // Note that 4062 (not all labels are handled and default is missing) is enabled
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic push
+// For simplicity, benchmarking-only helpers are always enabled
+#  pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+namespace Catch {
+
+namespace {
+
+// Formatter impl for ConsoleReporter
+class ConsoleAssertionPrinter {
+public:
+    ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
+    ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
+    ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
+        : stream(_stream),
+        stats(_stats),
+        result(_stats.assertionResult),
+        colour(Colour::None),
+        message(result.getMessage()),
+        messages(_stats.infoMessages),
+        printInfoMessages(_printInfoMessages) {
+        switch (result.getResultType()) {
+        case ResultWas::Ok:
+            colour = Colour::Success;
+            passOrFail = "PASSED";
+            //if( result.hasMessage() )
+            if (_stats.infoMessages.size() == 1)
+                messageLabel = "with message";
+            if (_stats.infoMessages.size() > 1)
+                messageLabel = "with messages";
+            break;
+        case ResultWas::ExpressionFailed:
+            if (result.isOk()) {
+                colour = Colour::Success;
+                passOrFail = "FAILED - but was ok";
+            } else {
+                colour = Colour::Error;
+                passOrFail = "FAILED";
+            }
+            if (_stats.infoMessages.size() == 1)
+                messageLabel = "with message";
+            if (_stats.infoMessages.size() > 1)
+                messageLabel = "with messages";
+            break;
+        case ResultWas::ThrewException:
+            colour = Colour::Error;
+            passOrFail = "FAILED";
+            messageLabel = "due to unexpected exception with ";
+            if (_stats.infoMessages.size() == 1)
+                messageLabel += "message";
+            if (_stats.infoMessages.size() > 1)
+                messageLabel += "messages";
+            break;
+        case ResultWas::FatalErrorCondition:
+            colour = Colour::Error;
+            passOrFail = "FAILED";
+            messageLabel = "due to a fatal error condition";
+            break;
+        case ResultWas::DidntThrowException:
+            colour = Colour::Error;
+            passOrFail = "FAILED";
+            messageLabel = "because no exception was thrown where one was expected";
+            break;
+        case ResultWas::Info:
+            messageLabel = "info";
+            break;
+        case ResultWas::Warning:
+            messageLabel = "warning";
+            break;
+        case ResultWas::ExplicitFailure:
+            passOrFail = "FAILED";
+            colour = Colour::Error;
+            if (_stats.infoMessages.size() == 1)
+                messageLabel = "explicitly with message";
+            if (_stats.infoMessages.size() > 1)
+                messageLabel = "explicitly with messages";
+            break;
+            // These cases are here to prevent compiler warnings
+        case ResultWas::Unknown:
+        case ResultWas::FailureBit:
+        case ResultWas::Exception:
+            passOrFail = "** internal error **";
+            colour = Colour::Error;
+            break;
+        }
+    }
+
+    void print() const {
+        printSourceInfo();
+        if (stats.totals.assertions.total() > 0) {
+            printResultType();
+            printOriginalExpression();
+            printReconstructedExpression();
+        } else {
+            stream << '\n';
+        }
+        printMessage();
+    }
+
+private:
+    void printResultType() const {
+        if (!passOrFail.empty()) {
+            Colour colourGuard(colour);
+            stream << passOrFail << ":\n";
+        }
+    }
+    void printOriginalExpression() const {
+        if (result.hasExpression()) {
+            Colour colourGuard(Colour::OriginalExpression);
+            stream << "  ";
+            stream << result.getExpressionInMacro();
+            stream << '\n';
+        }
+    }
+    void printReconstructedExpression() const {
+        if (result.hasExpandedExpression()) {
+            stream << "with expansion:\n";
+            Colour colourGuard(Colour::ReconstructedExpression);
+            stream << Column(result.getExpandedExpression()).indent(2) << '\n';
+        }
+    }
+    void printMessage() const {
+        if (!messageLabel.empty())
+            stream << messageLabel << ':' << '\n';
+        for (auto const& msg : messages) {
+            // If this assertion is a warning ignore any INFO messages
+            if (printInfoMessages || msg.type != ResultWas::Info)
+                stream << Column(msg.message).indent(2) << '\n';
+        }
+    }
+    void printSourceInfo() const {
+        Colour colourGuard(Colour::FileName);
+        stream << result.getSourceInfo() << ": ";
+    }
+
+    std::ostream& stream;
+    AssertionStats const& stats;
+    AssertionResult const& result;
+    Colour::Code colour;
+    std::string passOrFail;
+    std::string messageLabel;
+    std::string message;
+    std::vector<MessageInfo> messages;
+    bool printInfoMessages;
+};
+
+std::size_t makeRatio(std::size_t number, std::size_t total) {
+    std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
+    return (ratio == 0 && number > 0) ? 1 : ratio;
+}
+
+std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
+    if (i > j && i > k)
+        return i;
+    else if (j > k)
+        return j;
+    else
+        return k;
+}
+
+struct ColumnInfo {
+    enum Justification { Left, Right };
+    std::string name;
+    int width;
+    Justification justification;
+};
+struct ColumnBreak {};
+struct RowBreak {};
+
+class Duration {
+    enum class Unit {
+        Auto,
+        Nanoseconds,
+        Microseconds,
+        Milliseconds,
+        Seconds,
+        Minutes
+    };
+    static const uint64_t s_nanosecondsInAMicrosecond = 1000;
+    static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
+    static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
+    static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
+
+    double m_inNanoseconds;
+    Unit m_units;
+
+public:
+    explicit Duration(double inNanoseconds, Unit units = Unit::Microseconds)
+        : m_inNanoseconds(inNanoseconds),
+        m_units(units) {
+        if (m_units == Unit::Auto) {
+            if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
+                m_units = Unit::Nanoseconds;
+            else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
+                m_units = Unit::Microseconds;
+            else if (m_inNanoseconds < s_nanosecondsInASecond)
+                m_units = Unit::Milliseconds;
+            else if (m_inNanoseconds < s_nanosecondsInAMinute)
+                m_units = Unit::Seconds;
+            else
+                m_units = Unit::Minutes;
+        }
+
+    }
+
+    auto value() const -> double {
+        switch (m_units) {
+        case Unit::Microseconds:
+            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
+        case Unit::Milliseconds:
+            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
+        case Unit::Seconds:
+            return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
+        case Unit::Minutes:
+            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
+        default:
+            return m_inNanoseconds;
+        }
+    }
+    auto unitsAsString() const -> std::string {
+        switch (m_units) {
+        case Unit::Nanoseconds:
+            return "ns";
+        case Unit::Microseconds:
+            return "us";
+        case Unit::Milliseconds:
+            return "ms";
+        case Unit::Seconds:
+            return "s";
+        case Unit::Minutes:
+            return "m";
+        default:
+            return "** internal error **";
+        }
+
+    }
+    friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
+        return os << std::fixed << duration.value() << ' ' << duration.unitsAsString();
+    }
+};
+} // end anon namespace
+
+class TablePrinter {
+    std::ostream& m_os;
+    std::vector<ColumnInfo> m_columnInfos;
+    std::ostringstream m_oss;
+    int m_currentColumn = -1;
+    bool m_isOpen = false;
+
+public:
+    TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
+    :   m_os( os ),
+        m_columnInfos( std::move( columnInfos ) ) {}
+
+    auto columnInfos() const -> std::vector<ColumnInfo> const& {
+        return m_columnInfos;
+    }
+
+    void open() {
+        if (!m_isOpen) {
+            m_isOpen = true;
+            *this << RowBreak();
+
+                       Columns headerCols;
+                       Spacer spacer(2);
+                       for (auto const& info : m_columnInfos) {
+                               headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
+                               headerCols += spacer;
+                       }
+                       m_os << headerCols << '\n';
+
+            m_os << Catch::getLineOfChars<'-'>() << '\n';
+        }
+    }
+    void close() {
+        if (m_isOpen) {
+            *this << RowBreak();
+            m_os << std::endl;
+            m_isOpen = false;
+        }
+    }
+
+    template<typename T>
+    friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
+        tp.m_oss << value;
+        return tp;
+    }
+
+    friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
+        auto colStr = tp.m_oss.str();
+        const auto strSize = colStr.size();
+        tp.m_oss.str("");
+        tp.open();
+        if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
+            tp.m_currentColumn = -1;
+            tp.m_os << '\n';
+        }
+        tp.m_currentColumn++;
+
+        auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
+        auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
+            ? std::string(colInfo.width - (strSize + 1), ' ')
+            : std::string();
+        if (colInfo.justification == ColumnInfo::Left)
+            tp.m_os << colStr << padding << ' ';
+        else
+            tp.m_os << padding << colStr << ' ';
+        return tp;
+    }
+
+    friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
+        if (tp.m_currentColumn > 0) {
+            tp.m_os << '\n';
+            tp.m_currentColumn = -1;
+        }
+        return tp;
+    }
+};
+
+ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
+    : StreamingReporterBase(config),
+    m_tablePrinter(new TablePrinter(config.stream(),
+        [&config]() -> std::vector<ColumnInfo> {
+        if (config.fullConfig()->benchmarkNoAnalysis())
+        {
+            return{
+                { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
+                { "     samples", 14, ColumnInfo::Right },
+                { "  iterations", 14, ColumnInfo::Right },
+                { "        mean", 14, ColumnInfo::Right }
+            };
+        }
+        else
+        {
+            return{
+                { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
+                { "samples      mean       std dev", 14, ColumnInfo::Right },
+                { "iterations   low mean   low std dev", 14, ColumnInfo::Right },
+                { "estimated    high mean  high std dev", 14, ColumnInfo::Right }
+            };
+        }
+    }())) {}
+ConsoleReporter::~ConsoleReporter() = default;
+
+std::string ConsoleReporter::getDescription() {
+    return "Reports test results as plain lines of text";
+}
+
+void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
+    stream << "No test cases matched '" << spec << '\'' << std::endl;
+}
+
+void ConsoleReporter::reportInvalidArguments(std::string const&arg){
+    stream << "Invalid Filter: " << arg << std::endl;
+}
+
+void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
+
+bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
+    AssertionResult const& result = _assertionStats.assertionResult;
+
+    bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
+
+    // Drop out if result was successful but we're not printing them.
+    if (!includeResults && result.getResultType() != ResultWas::Warning)
+        return false;
+
+    lazyPrint();
+
+    ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
+    printer.print();
+    stream << std::endl;
+    return true;
+}
+
+void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
+    m_tablePrinter->close();
+    m_headerPrinted = false;
+    StreamingReporterBase::sectionStarting(_sectionInfo);
+}
+void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
+    m_tablePrinter->close();
+    if (_sectionStats.missingAssertions) {
+        lazyPrint();
+        Colour colour(Colour::ResultError);
+        if (m_sectionStack.size() > 1)
+            stream << "\nNo assertions in section";
+        else
+            stream << "\nNo assertions in test case";
+        stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+    }
+    double dur = _sectionStats.durationInSeconds;
+    if (shouldShowDuration(*m_config, dur)) {
+        stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+    }
+    if (m_headerPrinted) {
+        m_headerPrinted = false;
+    }
+    StreamingReporterBase::sectionEnded(_sectionStats);
+}
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+void ConsoleReporter::benchmarkPreparing(std::string const& name) {
+       lazyPrintWithoutClosingBenchmarkTable();
+
+       auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
+
+       bool firstLine = true;
+       for (auto line : nameCol) {
+               if (!firstLine)
+                       (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
+               else
+                       firstLine = false;
+
+               (*m_tablePrinter) << line << ColumnBreak();
+       }
+}
+
+void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
+    (*m_tablePrinter) << info.samples << ColumnBreak()
+        << info.iterations << ColumnBreak();
+    if (!m_config->benchmarkNoAnalysis())
+        (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
+}
+void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
+    if (m_config->benchmarkNoAnalysis())
+    {
+        (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
+    }
+    else
+    {
+        (*m_tablePrinter) << ColumnBreak()
+            << Duration(stats.mean.point.count()) << ColumnBreak()
+            << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
+            << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
+            << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
+            << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
+            << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
+    }
+}
+
+void ConsoleReporter::benchmarkFailed(std::string const& error) {
+       Colour colour(Colour::Red);
+    (*m_tablePrinter)
+        << "Benchmark failed (" << error << ')'
+        << ColumnBreak() << RowBreak();
+}
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
+    m_tablePrinter->close();
+    StreamingReporterBase::testCaseEnded(_testCaseStats);
+    m_headerPrinted = false;
+}
+void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
+    if (currentGroupInfo.used) {
+        printSummaryDivider();
+        stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+        printTotals(_testGroupStats.totals);
+        stream << '\n' << std::endl;
+    }
+    StreamingReporterBase::testGroupEnded(_testGroupStats);
+}
+void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
+    printTotalsDivider(_testRunStats.totals);
+    printTotals(_testRunStats.totals);
+    stream << std::endl;
+    StreamingReporterBase::testRunEnded(_testRunStats);
+}
+void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
+    StreamingReporterBase::testRunStarting(_testInfo);
+    printTestFilters();
+}
+
+void ConsoleReporter::lazyPrint() {
+
+    m_tablePrinter->close();
+    lazyPrintWithoutClosingBenchmarkTable();
+}
+
+void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
+
+    if (!currentTestRunInfo.used)
+        lazyPrintRunInfo();
+    if (!currentGroupInfo.used)
+        lazyPrintGroupInfo();
+
+    if (!m_headerPrinted) {
+        printTestCaseAndSectionHeader();
+        m_headerPrinted = true;
+    }
+}
+void ConsoleReporter::lazyPrintRunInfo() {
+    stream << '\n' << getLineOfChars<'~'>() << '\n';
+    Colour colour(Colour::SecondaryText);
+    stream << currentTestRunInfo->name
+        << " is a Catch v" << libraryVersion() << " host application.\n"
+        << "Run with -? for options\n\n";
+
+    if (m_config->rngSeed() != 0)
+        stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+    currentTestRunInfo.used = true;
+}
+void ConsoleReporter::lazyPrintGroupInfo() {
+    if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
+        printClosedHeader("Group: " + currentGroupInfo->name);
+        currentGroupInfo.used = true;
+    }
+}
+void ConsoleReporter::printTestCaseAndSectionHeader() {
+    assert(!m_sectionStack.empty());
+    printOpenHeader(currentTestCaseInfo->name);
+
+    if (m_sectionStack.size() > 1) {
+        Colour colourGuard(Colour::Headers);
+
+        auto
+            it = m_sectionStack.begin() + 1, // Skip first section (test case)
+            itEnd = m_sectionStack.end();
+        for (; it != itEnd; ++it)
+            printHeaderString(it->name, 2);
+    }
+
+    SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
+
+    stream << getLineOfChars<'-'>() << '\n';
+    Colour colourGuard(Colour::FileName);
+    stream << lineInfo << '\n';
+    stream << getLineOfChars<'.'>() << '\n' << std::endl;
+}
+
+void ConsoleReporter::printClosedHeader(std::string const& _name) {
+    printOpenHeader(_name);
+    stream << getLineOfChars<'.'>() << '\n';
+}
+void ConsoleReporter::printOpenHeader(std::string const& _name) {
+    stream << getLineOfChars<'-'>() << '\n';
+    {
+        Colour colourGuard(Colour::Headers);
+        printHeaderString(_name);
+    }
+}
+
+// if string has a : in first line will set indent to follow it on
+// subsequent lines
+void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
+    std::size_t i = _string.find(": ");
+    if (i != std::string::npos)
+        i += 2;
+    else
+        i = 0;
+    stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
+}
+
+struct SummaryColumn {
+
+    SummaryColumn( std::string _label, Colour::Code _colour )
+    :   label( std::move( _label ) ),
+        colour( _colour ) {}
+    SummaryColumn addRow( std::size_t count ) {
+        ReusableStringStream rss;
+        rss << count;
+        std::string row = rss.str();
+        for (auto& oldRow : rows) {
+            while (oldRow.size() < row.size())
+                oldRow = ' ' + oldRow;
+            while (oldRow.size() > row.size())
+                row = ' ' + row;
+        }
+        rows.push_back(row);
+        return *this;
+    }
+
+    std::string label;
+    Colour::Code colour;
+    std::vector<std::string> rows;
+
+};
+
+void ConsoleReporter::printTotals( Totals const& totals ) {
+    if (totals.testCases.total() == 0) {
+        stream << Colour(Colour::Warning) << "No tests ran\n";
+    } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
+        stream << Colour(Colour::ResultSuccess) << "All tests passed";
+        stream << " ("
+            << pluralise(totals.assertions.passed, "assertion") << " in "
+            << pluralise(totals.testCases.passed, "test case") << ')'
+            << '\n';
+    } else {
+
+        std::vector<SummaryColumn> columns;
+        columns.push_back(SummaryColumn("", Colour::None)
+                          .addRow(totals.testCases.total())
+                          .addRow(totals.assertions.total()));
+        columns.push_back(SummaryColumn("passed", Colour::Success)
+                          .addRow(totals.testCases.passed)
+                          .addRow(totals.assertions.passed));
+        columns.push_back(SummaryColumn("failed", Colour::ResultError)
+                          .addRow(totals.testCases.failed)
+                          .addRow(totals.assertions.failed));
+        columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
+                          .addRow(totals.testCases.failedButOk)
+                          .addRow(totals.assertions.failedButOk));
+
+        printSummaryRow("test cases", columns, 0);
+        printSummaryRow("assertions", columns, 1);
+    }
+}
+void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
+    for (auto col : cols) {
+        std::string value = col.rows[row];
+        if (col.label.empty()) {
+            stream << label << ": ";
+            if (value != "0")
+                stream << value;
+            else
+                stream << Colour(Colour::Warning) << "- none -";
+        } else if (value != "0") {
+            stream << Colour(Colour::LightGrey) << " | ";
+            stream << Colour(col.colour)
+                << value << ' ' << col.label;
+        }
+    }
+    stream << '\n';
+}
+
+void ConsoleReporter::printTotalsDivider(Totals const& totals) {
+    if (totals.testCases.total() > 0) {
+        std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
+        std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
+        std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
+        while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
+            findMax(failedRatio, failedButOkRatio, passedRatio)++;
+        while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
+            findMax(failedRatio, failedButOkRatio, passedRatio)--;
+
+        stream << Colour(Colour::Error) << std::string(failedRatio, '=');
+        stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
+        if (totals.testCases.allPassed())
+            stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
+        else
+            stream << Colour(Colour::Success) << std::string(passedRatio, '=');
+    } else {
+        stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
+    }
+    stream << '\n';
+}
+void ConsoleReporter::printSummaryDivider() {
+    stream << getLineOfChars<'-'>() << '\n';
+}
+
+void ConsoleReporter::printTestFilters() {
+    if (m_config->testSpec().hasFilters()) {
+        Colour guard(Colour::BrightYellow);
+        stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
+    }
+}
+
+CATCH_REGISTER_REPORTER("console", ConsoleReporter)
+
+} // end namespace Catch
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#if defined(__clang__)
+#  pragma clang diagnostic pop
+#endif
+// end catch_reporter_console.cpp
+// start catch_reporter_junit.cpp
+
+#include <cassert>
+#include <sstream>
+#include <ctime>
+#include <algorithm>
+#include <iomanip>
+
+namespace Catch {
+
+    namespace {
+        std::string getCurrentTimestamp() {
+            // Beware, this is not reentrant because of backward compatibility issues
+            // Also, UTC only, again because of backward compatibility (%z is C++11)
+            time_t rawtime;
+            std::time(&rawtime);
+            auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
+
+#ifdef _MSC_VER
+            std::tm timeInfo = {};
+            gmtime_s(&timeInfo, &rawtime);
+#else
+            std::tm* timeInfo;
+            timeInfo = std::gmtime(&rawtime);
+#endif
+
+            char timeStamp[timeStampSize];
+            const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
+
+#ifdef _MSC_VER
+            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
+#else
+            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
+#endif
+            return std::string(timeStamp, timeStampSize-1);
+        }
+
+        std::string fileNameTag(const std::vector<std::string> &tags) {
+            auto it = std::find_if(begin(tags),
+                                   end(tags),
+                                   [] (std::string const& tag) {return tag.front() == '#'; });
+            if (it != tags.end())
+                return it->substr(1);
+            return std::string();
+        }
+
+        // Formats the duration in seconds to 3 decimal places.
+        // This is done because some genius defined Maven Surefire schema
+        // in a way that only accepts 3 decimal places, and tools like
+        // Jenkins use that schema for validation JUnit reporter output.
+        std::string formatDuration( double seconds ) {
+            ReusableStringStream rss;
+            rss << std::fixed << std::setprecision( 3 ) << seconds;
+            return rss.str();
+        }
+
+    } // anonymous namespace
+
+    JunitReporter::JunitReporter( ReporterConfig const& _config )
+        :   CumulativeReporterBase( _config ),
+            xml( _config.stream() )
+        {
+            m_reporterPrefs.shouldRedirectStdOut = true;
+            m_reporterPrefs.shouldReportAllAssertions = true;
+        }
+
+    JunitReporter::~JunitReporter() {}
+
+    std::string JunitReporter::getDescription() {
+        return "Reports test results in an XML format that looks like Ant's junitreport target";
+    }
+
+    void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
+
+    void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
+        CumulativeReporterBase::testRunStarting( runInfo );
+        xml.startElement( "testsuites" );
+    }
+
+    void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
+        suiteTimer.start();
+        stdOutForSuite.clear();
+        stdErrForSuite.clear();
+        unexpectedExceptions = 0;
+        CumulativeReporterBase::testGroupStarting( groupInfo );
+    }
+
+    void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
+        m_okToFail = testCaseInfo.okToFail();
+    }
+
+    bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
+        if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
+            unexpectedExceptions++;
+        return CumulativeReporterBase::assertionEnded( assertionStats );
+    }
+
+    void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+        stdOutForSuite += testCaseStats.stdOut;
+        stdErrForSuite += testCaseStats.stdErr;
+        CumulativeReporterBase::testCaseEnded( testCaseStats );
+    }
+
+    void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+        double suiteTime = suiteTimer.getElapsedSeconds();
+        CumulativeReporterBase::testGroupEnded( testGroupStats );
+        writeGroup( *m_testGroups.back(), suiteTime );
+    }
+
+    void JunitReporter::testRunEndedCumulative() {
+        xml.endElement();
+    }
+
+    void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+        XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+
+        TestGroupStats const& stats = groupNode.value;
+        xml.writeAttribute( "name", stats.groupInfo.name );
+        xml.writeAttribute( "errors", unexpectedExceptions );
+        xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+        xml.writeAttribute( "tests", stats.totals.assertions.total() );
+        xml.writeAttribute( "hostname", "tbd" ); // !TBD
+        if( m_config->showDurations() == ShowDurations::Never )
+            xml.writeAttribute( "time", "" );
+        else
+            xml.writeAttribute( "time", formatDuration( suiteTime ) );
+        xml.writeAttribute( "timestamp", getCurrentTimestamp() );
+
+        // Write properties if there are any
+        if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
+            auto properties = xml.scopedElement("properties");
+            if (m_config->hasTestFilters()) {
+                xml.scopedElement("property")
+                    .writeAttribute("name", "filters")
+                    .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
+            }
+            if (m_config->rngSeed() != 0) {
+                xml.scopedElement("property")
+                    .writeAttribute("name", "random-seed")
+                    .writeAttribute("value", m_config->rngSeed());
+            }
+        }
+
+        // Write test cases
+        for( auto const& child : groupNode.children )
+            writeTestCase( *child );
+
+        xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
+        xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
+    }
+
+    void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
+        TestCaseStats const& stats = testCaseNode.value;
+
+        // All test cases have exactly one section - which represents the
+        // test case itself. That section may have 0-n nested sections
+        assert( testCaseNode.children.size() == 1 );
+        SectionNode const& rootSection = *testCaseNode.children.front();
+
+        std::string className = stats.testInfo.className;
+
+        if( className.empty() ) {
+            className = fileNameTag(stats.testInfo.tags);
+            if ( className.empty() )
+                className = "global";
+        }
+
+        if ( !m_config->name().empty() )
+            className = m_config->name() + "." + className;
+
+        writeSection( className, "", rootSection, stats.testInfo.okToFail() );
+    }
+
+    void JunitReporter::writeSection( std::string const& className,
+                                      std::string const& rootName,
+                                      SectionNode const& sectionNode,
+                                      bool testOkToFail) {
+        std::string name = trim( sectionNode.stats.sectionInfo.name );
+        if( !rootName.empty() )
+            name = rootName + '/' + name;
+
+        if( !sectionNode.assertions.empty() ||
+            !sectionNode.stdOut.empty() ||
+            !sectionNode.stdErr.empty() ) {
+            XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+            if( className.empty() ) {
+                xml.writeAttribute( "classname", name );
+                xml.writeAttribute( "name", "root" );
+            }
+            else {
+                xml.writeAttribute( "classname", className );
+                xml.writeAttribute( "name", name );
+            }
+            xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) );
+            // This is not ideal, but it should be enough to mimic gtest's
+            // junit output.
+            // Ideally the JUnit reporter would also handle `skipTest`
+            // events and write those out appropriately.
+            xml.writeAttribute( "status", "run" );
+
+            if (sectionNode.stats.assertions.failedButOk) {
+                xml.scopedElement("skipped")
+                    .writeAttribute("message", "TEST_CASE tagged with !mayfail");
+            }
+
+            writeAssertions( sectionNode );
+
+            if( !sectionNode.stdOut.empty() )
+                xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
+            if( !sectionNode.stdErr.empty() )
+                xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
+        }
+        for( auto const& childNode : sectionNode.childSections )
+            if( className.empty() )
+                writeSection( name, "", *childNode, testOkToFail );
+            else
+                writeSection( className, name, *childNode, testOkToFail );
+    }
+
+    void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
+        for( auto const& assertion : sectionNode.assertions )
+            writeAssertion( assertion );
+    }
+
+    void JunitReporter::writeAssertion( AssertionStats const& stats ) {
+        AssertionResult const& result = stats.assertionResult;
+        if( !result.isOk() ) {
+            std::string elementName;
+            switch( result.getResultType() ) {
+                case ResultWas::ThrewException:
+                case ResultWas::FatalErrorCondition:
+                    elementName = "error";
+                    break;
+                case ResultWas::ExplicitFailure:
+                case ResultWas::ExpressionFailed:
+                case ResultWas::DidntThrowException:
+                    elementName = "failure";
+                    break;
+
+                // We should never see these here:
+                case ResultWas::Info:
+                case ResultWas::Warning:
+                case ResultWas::Ok:
+                case ResultWas::Unknown:
+                case ResultWas::FailureBit:
+                case ResultWas::Exception:
+                    elementName = "internalError";
+                    break;
+            }
+
+            XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+            xml.writeAttribute( "message", result.getExpression() );
+            xml.writeAttribute( "type", result.getTestMacroName() );
+
+            ReusableStringStream rss;
+            if (stats.totals.assertions.total() > 0) {
+                rss << "FAILED" << ":\n";
+                if (result.hasExpression()) {
+                    rss << "  ";
+                    rss << result.getExpressionInMacro();
+                    rss << '\n';
+                }
+                if (result.hasExpandedExpression()) {
+                    rss << "with expansion:\n";
+                    rss << Column(result.getExpandedExpression()).indent(2) << '\n';
+                }
+            } else {
+                rss << '\n';
+            }
+
+            if( !result.getMessage().empty() )
+                rss << result.getMessage() << '\n';
+            for( auto const& msg : stats.infoMessages )
+                if( msg.type == ResultWas::Info )
+                    rss << msg.message << '\n';
+
+            rss << "at " << result.getSourceInfo();
+            xml.writeText( rss.str(), XmlFormatting::Newline );
+        }
+    }
+
+    CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+// end catch_reporter_junit.cpp
+// start catch_reporter_listening.cpp
+
+#include <cassert>
+
+namespace Catch {
+
+    ListeningReporter::ListeningReporter() {
+        // We will assume that listeners will always want all assertions
+        m_preferences.shouldReportAllAssertions = true;
+    }
+
+    void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
+        m_listeners.push_back( std::move( listener ) );
+    }
+
+    void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
+        assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
+        m_reporter = std::move( reporter );
+        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
+    }
+
+    ReporterPreferences ListeningReporter::getPreferences() const {
+        return m_preferences;
+    }
+
+    std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
+        return std::set<Verbosity>{ };
+    }
+
+    void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->noMatchingTestCases( spec );
+        }
+        m_reporter->noMatchingTestCases( spec );
+    }
+
+    void ListeningReporter::reportInvalidArguments(std::string const&arg){
+        for ( auto const& listener : m_listeners ) {
+            listener->reportInvalidArguments( arg );
+        }
+        m_reporter->reportInvalidArguments( arg );
+    }
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void ListeningReporter::benchmarkPreparing( std::string const& name ) {
+               for (auto const& listener : m_listeners) {
+                       listener->benchmarkPreparing(name);
+               }
+               m_reporter->benchmarkPreparing(name);
+       }
+    void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->benchmarkStarting( benchmarkInfo );
+        }
+        m_reporter->benchmarkStarting( benchmarkInfo );
+    }
+    void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->benchmarkEnded( benchmarkStats );
+        }
+        m_reporter->benchmarkEnded( benchmarkStats );
+    }
+
+       void ListeningReporter::benchmarkFailed( std::string const& error ) {
+               for (auto const& listener : m_listeners) {
+                       listener->benchmarkFailed(error);
+               }
+               m_reporter->benchmarkFailed(error);
+       }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+    void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->testRunStarting( testRunInfo );
+        }
+        m_reporter->testRunStarting( testRunInfo );
+    }
+
+    void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->testGroupStarting( groupInfo );
+        }
+        m_reporter->testGroupStarting( groupInfo );
+    }
+
+    void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->testCaseStarting( testInfo );
+        }
+        m_reporter->testCaseStarting( testInfo );
+    }
+
+    void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->sectionStarting( sectionInfo );
+        }
+        m_reporter->sectionStarting( sectionInfo );
+    }
+
+    void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->assertionStarting( assertionInfo );
+        }
+        m_reporter->assertionStarting( assertionInfo );
+    }
+
+    // The return value indicates if the messages buffer should be cleared:
+    bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
+        for( auto const& listener : m_listeners ) {
+            static_cast<void>( listener->assertionEnded( assertionStats ) );
+        }
+        return m_reporter->assertionEnded( assertionStats );
+    }
+
+    void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->sectionEnded( sectionStats );
+        }
+        m_reporter->sectionEnded( sectionStats );
+    }
+
+    void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->testCaseEnded( testCaseStats );
+        }
+        m_reporter->testCaseEnded( testCaseStats );
+    }
+
+    void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->testGroupEnded( testGroupStats );
+        }
+        m_reporter->testGroupEnded( testGroupStats );
+    }
+
+    void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->testRunEnded( testRunStats );
+        }
+        m_reporter->testRunEnded( testRunStats );
+    }
+
+    void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
+        for ( auto const& listener : m_listeners ) {
+            listener->skipTest( testInfo );
+        }
+        m_reporter->skipTest( testInfo );
+    }
+
+    bool ListeningReporter::isMulti() const {
+        return true;
+    }
+
+} // end namespace Catch
+// end catch_reporter_listening.cpp
+// start catch_reporter_xml.cpp
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
+                              // Note that 4062 (not all labels are handled
+                              // and default is missing) is enabled
+#endif
+
+namespace Catch {
+    XmlReporter::XmlReporter( ReporterConfig const& _config )
+    :   StreamingReporterBase( _config ),
+        m_xml(_config.stream())
+    {
+        m_reporterPrefs.shouldRedirectStdOut = true;
+        m_reporterPrefs.shouldReportAllAssertions = true;
+    }
+
+    XmlReporter::~XmlReporter() = default;
+
+    std::string XmlReporter::getDescription() {
+        return "Reports test results as an XML document";
+    }
+
+    std::string XmlReporter::getStylesheetRef() const {
+        return std::string();
+    }
+
+    void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
+        m_xml
+            .writeAttribute( "filename", sourceInfo.file )
+            .writeAttribute( "line", sourceInfo.line );
+    }
+
+    void XmlReporter::noMatchingTestCases( std::string const& s ) {
+        StreamingReporterBase::noMatchingTestCases( s );
+    }
+
+    void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
+        StreamingReporterBase::testRunStarting( testInfo );
+        std::string stylesheetRef = getStylesheetRef();
+        if( !stylesheetRef.empty() )
+            m_xml.writeStylesheetRef( stylesheetRef );
+        m_xml.startElement( "Catch" );
+        if( !m_config->name().empty() )
+            m_xml.writeAttribute( "name", m_config->name() );
+        if (m_config->testSpec().hasFilters())
+            m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
+        if( m_config->rngSeed() != 0 )
+            m_xml.scopedElement( "Randomness" )
+                .writeAttribute( "seed", m_config->rngSeed() );
+    }
+
+    void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
+        StreamingReporterBase::testGroupStarting( groupInfo );
+        m_xml.startElement( "Group" )
+            .writeAttribute( "name", groupInfo.name );
+    }
+
+    void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
+        StreamingReporterBase::testCaseStarting(testInfo);
+        m_xml.startElement( "TestCase" )
+            .writeAttribute( "name", trim( testInfo.name ) )
+            .writeAttribute( "description", testInfo.description )
+            .writeAttribute( "tags", testInfo.tagsAsString() );
+
+        writeSourceInfo( testInfo.lineInfo );
+
+        if ( m_config->showDurations() == ShowDurations::Always )
+            m_testCaseTimer.start();
+        m_xml.ensureTagClosed();
+    }
+
+    void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
+        StreamingReporterBase::sectionStarting( sectionInfo );
+        if( m_sectionDepth++ > 0 ) {
+            m_xml.startElement( "Section" )
+                .writeAttribute( "name", trim( sectionInfo.name ) );
+            writeSourceInfo( sectionInfo.lineInfo );
+            m_xml.ensureTagClosed();
+        }
+    }
+
+    void XmlReporter::assertionStarting( AssertionInfo const& ) { }
+
+    bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
+
+        AssertionResult const& result = assertionStats.assertionResult;
+
+        bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
+
+        if( includeResults || result.getResultType() == ResultWas::Warning ) {
+            // Print any info messages in <Info> tags.
+            for( auto const& msg : assertionStats.infoMessages ) {
+                if( msg.type == ResultWas::Info && includeResults ) {
+                    m_xml.scopedElement( "Info" )
+                            .writeText( msg.message );
+                } else if ( msg.type == ResultWas::Warning ) {
+                    m_xml.scopedElement( "Warning" )
+                            .writeText( msg.message );
+                }
+            }
+        }
+
+        // Drop out if result was successful but we're not printing them.
+        if( !includeResults && result.getResultType() != ResultWas::Warning )
+            return true;
+
+        // Print the expression if there is one.
+        if( result.hasExpression() ) {
+            m_xml.startElement( "Expression" )
+                .writeAttribute( "success", result.succeeded() )
+                .writeAttribute( "type", result.getTestMacroName() );
+
+            writeSourceInfo( result.getSourceInfo() );
+
+            m_xml.scopedElement( "Original" )
+                .writeText( result.getExpression() );
+            m_xml.scopedElement( "Expanded" )
+                .writeText( result.getExpandedExpression() );
+        }
+
+        // And... Print a result applicable to each result type.
+        switch( result.getResultType() ) {
+            case ResultWas::ThrewException:
+                m_xml.startElement( "Exception" );
+                writeSourceInfo( result.getSourceInfo() );
+                m_xml.writeText( result.getMessage() );
+                m_xml.endElement();
+                break;
+            case ResultWas::FatalErrorCondition:
+                m_xml.startElement( "FatalErrorCondition" );
+                writeSourceInfo( result.getSourceInfo() );
+                m_xml.writeText( result.getMessage() );
+                m_xml.endElement();
+                break;
+            case ResultWas::Info:
+                m_xml.scopedElement( "Info" )
+                    .writeText( result.getMessage() );
+                break;
+            case ResultWas::Warning:
+                // Warning will already have been written
+                break;
+            case ResultWas::ExplicitFailure:
+                m_xml.startElement( "Failure" );
+                writeSourceInfo( result.getSourceInfo() );
+                m_xml.writeText( result.getMessage() );
+                m_xml.endElement();
+                break;
+            default:
+                break;
+        }
+
+        if( result.hasExpression() )
+            m_xml.endElement();
+
+        return true;
+    }
+
+    void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
+        StreamingReporterBase::sectionEnded( sectionStats );
+        if( --m_sectionDepth > 0 ) {
+            XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+            e.writeAttribute( "successes", sectionStats.assertions.passed );
+            e.writeAttribute( "failures", sectionStats.assertions.failed );
+            e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+            if ( m_config->showDurations() == ShowDurations::Always )
+                e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+            m_xml.endElement();
+        }
+    }
+
+    void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+        StreamingReporterBase::testCaseEnded( testCaseStats );
+        XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+        e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+        if ( m_config->showDurations() == ShowDurations::Always )
+            e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+        if( !testCaseStats.stdOut.empty() )
+            m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
+        if( !testCaseStats.stdErr.empty() )
+            m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
+
+        m_xml.endElement();
+    }
+
+    void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+        StreamingReporterBase::testGroupEnded( testGroupStats );
+        // TODO: Check testGroupStats.aborting and act accordingly.
+        m_xml.scopedElement( "OverallResults" )
+            .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+            .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+            .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+        m_xml.scopedElement( "OverallResultsCases")
+            .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
+            .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
+            .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
+        m_xml.endElement();
+    }
+
+    void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
+        StreamingReporterBase::testRunEnded( testRunStats );
+        m_xml.scopedElement( "OverallResults" )
+            .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+            .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+            .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+        m_xml.scopedElement( "OverallResultsCases")
+            .writeAttribute( "successes", testRunStats.totals.testCases.passed )
+            .writeAttribute( "failures", testRunStats.totals.testCases.failed )
+            .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
+        m_xml.endElement();
+    }
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+    void XmlReporter::benchmarkPreparing(std::string const& name) {
+        m_xml.startElement("BenchmarkResults")
+            .writeAttribute("name", name);
+    }
+
+    void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
+        m_xml.writeAttribute("samples", info.samples)
+            .writeAttribute("resamples", info.resamples)
+            .writeAttribute("iterations", info.iterations)
+            .writeAttribute("clockResolution", info.clockResolution)
+            .writeAttribute("estimatedDuration", info.estimatedDuration)
+            .writeComment("All values in nano seconds");
+    }
+
+    void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
+        m_xml.startElement("mean")
+            .writeAttribute("value", benchmarkStats.mean.point.count())
+            .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
+            .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
+            .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
+        m_xml.endElement();
+        m_xml.startElement("standardDeviation")
+            .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
+            .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
+            .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
+            .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
+        m_xml.endElement();
+        m_xml.startElement("outliers")
+            .writeAttribute("variance", benchmarkStats.outlierVariance)
+            .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
+            .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
+            .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
+            .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
+        m_xml.endElement();
+        m_xml.endElement();
+    }
+
+    void XmlReporter::benchmarkFailed(std::string const &error) {
+        m_xml.scopedElement("failed").
+            writeAttribute("message", error);
+        m_xml.endElement();
+    }
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+    CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+// end catch_reporter_xml.cpp
+
+namespace Catch {
+    LeakDetector leakDetector;
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// end catch_impl.hpp
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// start catch_default_main.hpp
+
+#ifndef __OBJC__
+
+#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
+// Standard C/C++ Win32 Unicode wmain entry point
+extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
+#else
+// Standard C/C++ main entry point
+int main (int argc, char * argv[]) {
+#endif
+
+    return Catch::Session().run( argc, argv );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+    Catch::registerTestMethods();
+    int result = Catch::Session().run( argc, (char**)argv );
+
+#if !CATCH_ARC_ENABLED
+    [pool drain];
+#endif
+
+    return result;
+}
+
+#endif // __OBJC__
+
+// end catch_default_main.hpp
+#endif
+
+#if !defined(CATCH_CONFIG_IMPL_ONLY)
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+#  undef CLARA_CONFIG_MAIN
+#endif
+
+#if !defined(CATCH_CONFIG_DISABLE)
+//////
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+
+#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
+#endif// CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+
+#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
+
+#define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
+
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
+#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
+#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
+
+#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
+#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
+#else
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
+#endif
+
+#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
+#define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )
+#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
+#else
+#define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )
+#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
+#endif
+
+// "BDD-style" convenience wrappers
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#define CATCH_BENCHMARK(...) \
+    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+#define CATCH_BENCHMARK_ADVANCED(name) \
+    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
+#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+
+#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
+#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+
+#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
+
+#define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
+
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
+#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
+#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
+#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
+
+#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
+#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
+#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
+#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#else
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
+#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
+#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
+#endif
+
+#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
+#define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
+#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
+#else
+#define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )
+#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
+#endif
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+
+#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
+
+#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+#define BENCHMARK(...) \
+    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
+#define BENCHMARK_ADVANCED(name) \
+    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)
+#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
+
+using Catch::Detail::Approx;
+
+#else // CATCH_CONFIG_DISABLE
+
+//////
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( ... )        (void)(0)
+#define CATCH_REQUIRE_FALSE( ... )  (void)(0)
+
+#define CATCH_REQUIRE_THROWS( ... ) (void)(0)
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif// CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
+
+#define CATCH_CHECK( ... )         (void)(0)
+#define CATCH_CHECK_FALSE( ... )   (void)(0)
+#define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
+#define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
+#define CATCH_CHECK_NOFAIL( ... )  (void)(0)
+
+#define CATCH_CHECK_THROWS( ... )  (void)(0)
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
+#define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CATCH_CHECK_NOTHROW( ... ) (void)(0)
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
+
+#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define CATCH_INFO( msg )          (void)(0)
+#define CATCH_UNSCOPED_INFO( msg ) (void)(0)
+#define CATCH_WARN( msg )          (void)(0)
+#define CATCH_CAPTURE( msg )       (void)(0)
+
+#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define CATCH_METHOD_AS_TEST_CASE( method, ... )
+#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
+#define CATCH_SECTION( ... )
+#define CATCH_DYNAMIC_SECTION( ... )
+#define CATCH_FAIL( ... ) (void)(0)
+#define CATCH_FAIL_CHECK( ... ) (void)(0)
+#define CATCH_SUCCEED( ... ) (void)(0)
+
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#else
+#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
+#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#endif
+
+// "BDD-style" convenience wrappers
+#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )
+#define CATCH_GIVEN( desc )
+#define CATCH_AND_GIVEN( desc )
+#define CATCH_WHEN( desc )
+#define CATCH_AND_WHEN( desc )
+#define CATCH_THEN( desc )
+#define CATCH_AND_THEN( desc )
+
+#define CATCH_STATIC_REQUIRE( ... )       (void)(0)
+#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( ... )       (void)(0)
+#define REQUIRE_FALSE( ... ) (void)(0)
+
+#define REQUIRE_THROWS( ... ) (void)(0)
+#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
+#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define REQUIRE_NOTHROW( ... ) (void)(0)
+
+#define CHECK( ... ) (void)(0)
+#define CHECK_FALSE( ... ) (void)(0)
+#define CHECKED_IF( ... ) if (__VA_ARGS__)
+#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
+#define CHECK_NOFAIL( ... ) (void)(0)
+
+#define CHECK_THROWS( ... )  (void)(0)
+#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
+#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+#define CHECK_NOTHROW( ... ) (void)(0)
+
+#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
+#define CHECK_THAT( arg, matcher ) (void)(0)
+
+#define REQUIRE_THAT( arg, matcher ) (void)(0)
+#endif // CATCH_CONFIG_DISABLE_MATCHERS
+
+#define INFO( msg ) (void)(0)
+#define UNSCOPED_INFO( msg ) (void)(0)
+#define WARN( msg ) (void)(0)
+#define CAPTURE( ... ) (void)(0)
+
+#define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+#define METHOD_AS_TEST_CASE( method, ... )
+#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
+#define SECTION( ... )
+#define DYNAMIC_SECTION( ... )
+#define FAIL( ... ) (void)(0)
+#define FAIL_CHECK( ... ) (void)(0)
+#define SUCCEED( ... ) (void)(0)
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))
+
+#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#else
+#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
+#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
+#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
+#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#endif
+
+#define STATIC_REQUIRE( ... )       (void)(0)
+#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
+
+// "BDD-style" convenience wrappers
+#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )
+
+#define GIVEN( desc )
+#define AND_GIVEN( desc )
+#define WHEN( desc )
+#define AND_WHEN( desc )
+#define THEN( desc )
+#define AND_THEN( desc )
+
+using Catch::Detail::Approx;
+
+#endif
+
+#endif // ! CATCH_CONFIG_IMPL_ONLY
+
+// start catch_reenable_warnings.h
+
+
+#ifdef __clang__
+#    ifdef __ICC // icpc defines the __clang__ macro
+#        pragma warning(pop)
+#    else
+#        pragma clang diagnostic pop
+#    endif
+#elif defined __GNUC__
+#    pragma GCC diagnostic pop
+#endif
+
+// end catch_reenable_warnings.h
+// end catch.hpp
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
index 884c4d3895ae64dee5e0e368bb17bd80062ab577..f0604a43df39e218514e634279fee64c3d64fac9 100644 (file)
@@ -1,3 +1,3 @@
-add_library(gmp mini-gmp.c)
+add_library(gmp STATIC mini-gmp.c)
 target_link_libraries(gmp)
 
index 0531712aecee032b54c2f86545b556c8f911905d..cdd1a7ead5983e02846837e633da5494e56367e4 100644 (file)
@@ -1,3 +1,3 @@
-add_library(jsoncpp jsoncpp.cpp)
+add_library(jsoncpp STATIC jsoncpp.cpp)
 target_link_libraries(jsoncpp)
 
index 5d0dc0f708d711704b6322bd5009b9043d0bf793..2de4840cb20ad76b59a0f739b5f2e5e6eec2e522 100644 (file)
@@ -1,12 +1,10 @@
-project(lua C)
+project(lua CXX)
 
 set(LUA_VERSION_MAJOR 5)
 set(LUA_VERSION_MINOR 1)
 set(LUA_VERSION_PATCH 4)
 set(LUA_VERSION "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
 
-set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-
 set(COMMON_CFLAGS)
 set(COMMON_LDFLAGS)
 set(LIBS)
@@ -50,19 +48,12 @@ if(LUA_ANSI)
        set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_ANSI")
 endif(LUA_ANSI)
 
-# COMMON_CFLAGS has no effect without this line
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_CFLAGS}")
-
-
-# Standard flags to use for each build type.
-if(CMAKE_COMPILER_IS_GNUCC)
-       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -Wall -Wextra -Wshadow -W -pedantic -std=gnu99")
-       set(CMAKE_C_FLAGS_RELEASE        "${CMAKE_C_FLAGS_RELEASE}     -O2")
-       set(CMAKE_C_FLAGS_DEBUG          "${CMAKE_C_FLAGS_DEBUG}       -O0 -g")
-       set(CMAKE_C_FLAGS_PROFILE        "${CMAKE_C_FLAGS_PROFILE}     -O1 -g")
-       set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_WITHDEBINFO} -O2 -g")
-endif(CMAKE_COMPILER_IS_GNUCC)
-
+# Standard flags to use
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|(Apple)?Clang")
+       set(COMMON_CFLAGS "${COMMON_CFLAGS} -pipe -Wall -Wextra -Wshadow -W -pedantic")
+endif()
 
-add_subdirectory(src build)
+# COMMON_CFLAGS has no effect without this line
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_CFLAGS}")
 
+add_subdirectory(src)
index 8f6cc1213d6779c2b0dbcd7c09176b30b346a214..2ca4f416854b507e52c0dae0ec7eb492e7a3fb5d 100644 (file)
@@ -31,24 +31,14 @@ set(LUA_CORE_SRC
        lvm.c
        lzio.c
 )
-set(LUA_LIB_HEADERS
-       lua.h
-       lualib.h
-       lauxlib.h
-       luaconf.h
-)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
-               ${CMAKE_CURRENT_BINARY_DIR})
 
-# Lua library.
+# Lua library
 add_library(lua STATIC ${LUA_CORE_SRC})
 target_link_libraries(lua ${LIBS})
-set(LUA_STATIC_LIB lua)
-set(LUA_LIBS lua)
-
-set_target_properties(${LUA_LIBS} PROPERTIES
+set_target_properties(lua PROPERTIES
        VERSION ${LUA_VERSION}
        CLEAN_DIRECT_OUTPUT 1
 )
 
+# Compile code as C++
+set_source_files_properties(${LUA_CORE_SRC} PROPERTIES LANGUAGE CXX)
index e2cb26163a2320cd5e27c89ba1e32cedbad41049..1521f0cbc573774658591dadf797e9d37c7f8654 100644 (file)
 #define LUA_INTEGER    ptrdiff_t
 
 
+/* MINETEST-SPECIFIC CHANGE: make sure API functions conform to the C ABI. */
+#if defined(__cplusplus)
+#define LUAI_API_EXTERN extern "C"
+#else
+#define LUAI_API_EXTERN extern
+#endif
+
+
 /*
 @@ LUA_API is a mark for all core API functions.
 @@ LUALIB_API is a mark for all standard library functions.
 #if defined(LUA_BUILD_AS_DLL)
 
 #if defined(LUA_CORE) || defined(LUA_LIB)
-#define LUA_API __declspec(dllexport)
+#define LUA_API LUAI_API_EXTERN __declspec(dllexport)
 #else
-#define LUA_API __declspec(dllimport)
+#define LUA_API LUAI_API_EXTERN __declspec(dllimport)
 #endif
 
 #else
 
-#define LUA_API                extern
+#define LUA_API                LUAI_API_EXTERN
 
 #endif
 
index b252f4f7043890857b7074ecddff75384d4497d2..4b4bda0c5e33b8894653563671f1e567d88f341c 100644 (file)
 # joystick_id = 0
 
 #    The type of joystick
-#    type: enum values: auto, generic, xbox
+#    type: enum values: auto, generic, xbox, dragonrise_gamecube
 # joystick_type = auto
 
 #    The time in seconds it takes between repeated events
 #    type: float min: 0.001
 # repeat_joystick_button_time = 0.17
 
-#    The deadzone of the joystick
+#    The dead zone of the joystick
 #    type: int
 # joystick_deadzone = 2048
 
 #    The sensitivity of the joystick axes for moving the
-#    ingame view frustum around.
+#    in-game view frustum around.
 #    type: float
 # joystick_frustum_sensitivity = 170
 
 
 ### Basic
 
-#    Whether nametag backgrounds should be shown by default.
+#    Whether name tag backgrounds should be shown by default.
 #    Mods may still set a background.
 #    type: bool
 # show_nametag_backgrounds = true
 #    type: bool
 # smooth_lighting = true
 
+#    Enables tradeoffs that reduce CPU load or increase rendering performance
+#    at the expense of minor visual glitches that do not impact game playability.
+#    type: bool
+# performance_tradeoffs = false
+
 #    Clouds are a client side effect.
 #    type: bool
 # enable_clouds = true
 
 ### Filtering
 
-#    Use mip mapping to scale textures. May slightly increase performance,
+#    Use mipmapping to scale textures. May slightly increase performance,
 #    especially when using a high resolution texture pack.
 #    Gamma correct downscaling is not supported.
 #    type: bool
 #    can be blurred, so automatically upscale them with nearest-neighbor
 #    interpolation to preserve crisp pixels. This sets the minimum texture size
 #    for the upscaled textures; higher values look sharper, but require more
-#    memory.  Powers of 2 are recommended. This setting is ONLY applies if
+#    memory. Powers of 2 are recommended. This setting is ONLY applied if
 #    bilinear/trilinear/anisotropic filtering is enabled.
 #    This is also used as the base node texture size for world-aligned
 #    texture autoscaling.
 #    type: bool
 # enable_dynamic_shadows = false
 
-#    Set the shadow strength.
+#    Set the shadow strength gamma.
+#    Adjusts the intensity of in-game dynamic shadows.
 #    Lower value means lighter shadows, higher value means darker shadows.
-#    type: float min: 0.05 max: 1
-# shadow_strength = 0.2
+#    type: float min: 0.1 max: 10
+# shadow_strength_gamma = 1.0
 
 #    Maximum distance to render shadows.
 #    type: float min: 10 max: 1000
 
 #    Texture size to render the shadow map on.
 #    This must be a power of two.
-#    Bigger numbers create better shadowsbut it is also more expensive.
+#    Bigger numbers create better shadows but it is also more expensive.
 #    type: int min: 128 max: 8192
 # shadow_map_texture_size = 1024
 
 #    type: bool
 # shadow_map_texture_32bit = true
 
-#    Enable poisson disk filtering.
-#    On true uses poisson disk to make "soft shadows". Otherwise uses PCF filtering.
+#    Enable Poisson disk filtering.
+#    On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering.
 #    type: bool
 # shadow_poisson_filter = true
 
-#    Define shadow filtering quality
-#    This simulates the soft shadows effect by applying a PCF or poisson disk
+#    Define shadow filtering quality.
+#    This simulates the soft shadows effect by applying a PCF or Poisson disk
 #    but also uses more resources.
 #    type: enum values: 0, 1, 2
 # shadow_filters = 1
 
-#    Enable colored shadows. 
+#    Enable colored shadows.
 #    On true translucent nodes cast colored shadows. This is expensive.
 #    type: bool
 # shadow_map_color = false
 
-#    Set the shadow update time.
-#    Lower value means shadows and map updates faster, but it consume more resources.
-#    Minimun value 0.001 seconds max value 0.2 seconds
-#    type: float min: 0.001 max: 0.2
-# shadow_update_time = 0.2
+#    Spread a complete update of shadow map over given amount of frames.
+#    Higher values might make shadows laggy, lower values
+#    will consume more resources.
+#    Minimum value: 1; maximum value: 16
+#    type: int min: 1 max: 16
+# shadow_update_frames = 8
 
 #    Set the soft shadow radius size.
-#    Lower values mean sharper shadows bigger values softer.
-#    Minimun value 1.0 and max value 10.0
+#    Lower values mean sharper shadows, bigger values mean softer shadows.
+#    Minimum value: 1.0; maximum value: 10.0
 #    type: float min: 1 max: 10
 # shadow_soft_radius = 1.0
 
-#    Set the tilt of Sun/Moon orbit in degrees
+#    Set the tilt of Sun/Moon orbit in degrees.
 #    Value of 0 means no tilt / vertical orbit.
-#    Minimun value 0.0 and max value 60.0
+#    Minimum value: 0.0; maximum value: 60.0
 #    type: float min: 0 max: 60
 # shadow_sky_body_orbit_tilt = 0.0
 
 #    Note: On Android, stick with OGLES1 if unsure! App may fail to start otherwise.
 #    On other platforms, OpenGL is recommended.
 #    Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)
-#    type: enum values: null, software, burningsvideo, direct3d8, direct3d9, opengl, ogles1, ogles2
+#    type: enum values: opengl, ogles1, ogles2
 # video_driver = opengl
 
 #    Radius of cloud area stated in number of 64 node cloud squares.
 # crosshair_color = (255,255,255)
 
 #    Crosshair alpha (opaqueness, between 0 and 255).
-#    Also controls the object crosshair color
+#    This also applies to the object crosshair.
 #    type: int min: 0 max: 255
 # crosshair_alpha = 255
 
 #    type: float
 # hud_hotbar_max_width = 1.0
 
-#    Modifies the size of the hudbar elements.
+#    Modifies the size of the HUD elements.
 #    type: float
 # hud_scaling = 1.0
 
 #    type: bool
 # show_entity_selectionbox = false
 
+#    Distance in nodes at which transparency depth sorting is enabled
+#    Use this to limit the performance impact of transparency depth sorting
+#    type: int min: 0 max: 128
+# transparency_sorting_distance = 16
+
 ## Menus
 
 #    Use a cloud animation for the main menu background.
 #    type: bool
 # tooltip_append_itemname = false
 
-#    Whether FreeType fonts are used, requires FreeType support to be compiled in.
-#    If disabled, bitmap and XML vectors fonts are used instead.
-#    type: bool
-# freetype = true
-
 #    type: bool
 # font_bold = false
 
 #    type: int min: 0 max: 255
 # font_shadow_alpha = 127
 
-#    Font size of the default font in point (pt).
+#    Font size of the default font where 1 unit = 1 pixel at 96 DPI
 #    type: int min: 1
 # font_size = 16
 
-#    Path to the default font.
-#    If “freetype” setting is enabled: Must be a TrueType font.
-#    If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
+#    For pixel-style fonts that do not scale well, this ensures that font sizes used
+#    with this font will always be divisible by this value, in pixels. For instance,
+#    a pixel font 16 pixels tall should have this set to 16, so it will only ever be
+#    sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32.
+#    type: int min: 1
+# font_size_divisible_by = 1
+
+#    Path to the default font. Must be a TrueType font.
 #    The fallback font will be used if the font cannot be loaded.
 #    type: filepath
 # font_path = fonts/Arimo-Regular.ttf
 #    type: filepath
 # font_path_bold_italic = fonts/Arimo-BoldItalic.ttf
 
-#    Font size of the monospace font in point (pt).
+#    Font size of the monospace font where 1 unit = 1 pixel at 96 DPI
 #    type: int min: 1
-# mono_font_size = 15
+# mono_font_size = 16
 
-#    Path to the monospace font.
-#    If “freetype” setting is enabled: Must be a TrueType font.
-#    If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
+#    For pixel-style fonts that do not scale well, this ensures that font sizes used
+#    with this font will always be divisible by this value, in pixels. For instance,
+#    a pixel font 16 pixels tall should have this set to 16, so it will only ever be
+#    sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32.
+#    type: int min: 1
+# mono_font_size_divisible_by = 1
+
+#    Path to the monospace font. Must be a TrueType font.
 #    This font is used for e.g. the console and profiler screen.
 #    type: filepath
 # mono_font_path = fonts/Cousine-Regular.ttf
 #    type: filepath
 # mono_font_path_bold_italic = fonts/Cousine-BoldItalic.ttf
 
-#    Path of the fallback font.
-#    If “freetype” setting is enabled: Must be a TrueType font.
-#    If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
+#    Path of the fallback font. Must be a TrueType font.
 #    This font will be used for certain languages or if the default font is unavailable.
 #    type: filepath
 # fallback_font_path = fonts/DroidSansFallbackFull.ttf
 # screenshot_path = screenshots
 
 #    Format of screenshots.
-#    type: enum values: png, jpg, bmp, pcx, ppm, tga
+#    type: enum values: png, jpg
 # screenshot_format = png
 
 #    Screenshot quality. Only used for JPEG format.
 #    type: int min: 1
 # screen_dpi = 72
 
+#    Adjust the detected display density, used for scaling UI elements.
+#    type: float
+# display_density_factor = 1
+
 #    Windows systems only: Start Minetest with the command line window in the background.
 #    Contains the same information as the file debug.txt (default name).
 #    type: bool
 # Client
 #
 
-#    If enabled, http links in chat can be middle-clicked or ctrl-left-clicked to open the link in the OS's default web browser.
+#    Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output.
 #    type: bool
-# clickable_chat_weblinks = false
+# clickable_chat_weblinks = true
 
-#    If clickable_chat_weblinks is enabled, specify the color (as 24-bit hexadecimal) of weblinks in chat.
+#    Optional override for chat weblink color.
 #    type: string
-# chat_weblink_color = #8888FF
+# chat_weblink_color =
 
 ## Network
 
 # remote_port = 30000
 
 #    Prometheus listener address.
-#    If minetest is compiled with ENABLE_PROMETHEUS option enabled,
+#    If Minetest is compiled with ENABLE_PROMETHEUS option enabled,
 #    enable metrics listener for Prometheus on that address.
-#    Metrics can be fetch on http://127.0.0.1:30000/metrics
+#    Metrics can be fetched on http://127.0.0.1:30000/metrics
 #    type: string
 # prometheus_listener_address = 127.0.0.1:30000
 
 #    type: int
 # max_packets_per_iteration = 1024
 
-#    ZLib compression level to use when sending mapblocks to the client.
-#    -1 - Zlib's default compression level
-#    0 - no compresson, fastest
+#    Compression level to use when sending mapblocks to the client.
+#    -1 - use default compression level
+#    0 - least compression, fastest
 #    9 - best compression, slowest
-#    (levels 1-3 use Zlib's "fast" method, 4-9 use the normal method)
 #    type: int min: -1 max: 9
 # map_compression_level_net = -1
 
 # ask_reconnect_on_crash = false
 
 #    From how far clients know about objects, stated in mapblocks (16 nodes).
-#    
+#
 #    Setting this larger than active_block_range will also cause the server
 #    to maintain active objects up to this distance in the direction the
 #    player is looking. (This can avoid mobs suddenly disappearing from view)
 # deprecated_lua_api_handling = log
 
 #    Number of extra blocks that can be loaded by /clearobjects at once.
-#    This is a trade-off between sqlite transaction overhead and
+#    This is a trade-off between SQLite transaction overhead and
 #    memory consumption (4096=100MB, as a rule of thumb).
 #    type: int
 # max_clearobjects_extra_loaded_blocks = 4096
 
 #    Maximum number of statically stored objects in a block.
 #    type: int
-# max_objects_per_block = 64
+# max_objects_per_block = 256
 
 #    See https://www.sqlite.org/pragma.html#pragma_synchronous
 #    type: enum values: 0, 1, 2
 # sqlite_synchronous = 2
 
-#    ZLib compression level to use when saving mapblocks to disk.
-#    -1 - Zlib's default compression level
-#    0 - no compresson, fastest
+#    Compression level to use when saving mapblocks to disk.
+#    -1 - use default compression level
+#    0 - least compression, fastest
 #    9 - best compression, slowest
-#    (levels 1-3 use Zlib's "fast" method, 4-9 use the normal method)
 #    type: int min: -1 max: 9
-# map_compression_level_disk = 3
+# map_compression_level_disk = -1
 
 #    Length of a server tick and the interval at which objects are generally updated over
 #    network.
 #    type: bool
 # instrument.lbm = true
 
-#    Instrument chatcommands on registration.
+#    Instrument chat commands on registration.
 #    type: bool
 # instrument.chatcommand = true
 
 #    -    action
 #    -    info
 #    -    verbose
-#    type: enum values: , none, error, warning, action, info, verbose
+#    -    trace
+#    type: enum values: , none, error, warning, action, info, verbose, trace
 # debug_log_level = action
 
 #    If the file size of debug.txt exceeds the number of megabytes specified in
 # debug_log_size_max = 50
 
 #    Minimal level of logging to be written to chat.
-#    type: enum values: , none, error, warning, action, info, verbose
+#    type: enum values: , none, error, warning, action, info, verbose, trace
 # chat_log_level = error
 
 #    Enable IPv6 support (for both client and server).
 #    Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).
 #    Only mapchunks completely within the mapgen limit are generated.
 #    Value is stored per-world.
-#    type: int min: 0 max: 31000
-# mapgen_limit = 31000
+#    type: int min: 0 max: 31007
+# mapgen_limit = 31007
 
 #    Global map generation attributes.
 #    In Mapgen v6 the 'decorations' flag controls all decorations except trees
-#    and junglegrass, in all other mapgens this flag controls all decorations.
+#    and jungle grass, in all other mapgens this flag controls all decorations.
 #    type: flags possible values: caves, dungeons, light, decorations, biomes, ores, nocaves, nodungeons, nolight, nodecorations, nobiomes, noores
 # mg_flags = caves,dungeons,light,decorations,biomes,ores
 
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Second of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise defining giant caverns.
 #    octaves     = 5,
 #    persistence = 0.63,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise defining terrain.
 #    octaves     = 2,
 #    persistence = 0.8,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 ## Mapgen V6
 #    octaves     = 5,
 #    persistence = 0.63,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise defining structure of river canyon walls.
 #    octaves     = 4,
 #    persistence = 0.75,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise defining structure of floatlands.
 #    octaves     = 4,
 #    persistence = 0.75,
 #    lacunarity  = 1.618,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise defining giant caverns.
 #    octaves     = 5,
 #    persistence = 0.63,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    First of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Second of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise that determines number of dungeons per mapchunk.
 #    octaves     = 2,
 #    persistence = 0.8,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 ## Mapgen Carpathian
 #    octaves     = 5,
 #    persistence = 0.55,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    First of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Second of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise defining giant caverns.
 #    octaves     = 5,
 #    persistence = 0.63,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise that determines number of dungeons per mapchunk.
 #    octaves     = 2,
 #    persistence = 0.8,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 ## Mapgen Flat
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Second of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise defining giant caverns.
 #    octaves     = 5,
 #    persistence = 0.63,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise that determines number of dungeons per mapchunk.
 #    octaves     = 2,
 #    persistence = 0.8,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 ## Mapgen Fractal
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Second of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    3D noise that determines number of dungeons per mapchunk.
 #    octaves     = 2,
 #    persistence = 0.8,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 ## Mapgen Valleys
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Second of two 3D noises that together define tunnels.
 #    octaves     = 3,
 #    persistence = 0.5,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    The depth of dirt or other biome filler node.
 #    octaves     = 6,
 #    persistence = 0.63,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Defines large-scale river channel structure.
 #    octaves     = 6,
 #    persistence = 0.8,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 #    Amplifies the valleys.
 #    octaves     = 2,
 #    persistence = 0.8,
 #    lacunarity  = 2.0,
-#    flags       = 
+#    flags       =
 # }
 
 ## Advanced
 # enable_mapgen_debug_info = false
 
 #    Maximum number of blocks that can be queued for loading.
-#    type: int
+#    type: int min: 1 max: 1000000
 # emergequeue_limit_total = 1024
 
 #    Maximum number of blocks to be queued that are to be loaded from file.
 #    This limit is enforced per player.
-#    type: int
+#    type: int min: 1 max: 1000000
 # emergequeue_limit_diskonly = 128
 
 #    Maximum number of blocks to be queued that are to be generated.
 #    This limit is enforced per player.
-#    type: int
+#    type: int min: 1 max: 1000000
 # emergequeue_limit_generate = 128
 
 #    Number of emerge threads to use.
index 0e5397b3731e40699c8a776171e873879b6dfe9e..951bb62213848909bc61f1064851a3f448a79083 100644 (file)
        </content_rating>
        <name>Minetest</name>
        <summary>Multiplayer infinite-world block sandbox game</summary>
+       <summary xml:lang="de">Mehrspieler-Sandkastenspiel mit unendlichen Blockwelten</summary>
        <description>
                <p>
                        Minetest is an infinite-world block sandbox game and game engine.
+               </p><p xml:lang="de">
+                       Minetest ist ein Sandkastenspiel und eine Spielengine mit unendlichen Welten.
                </p><p>
                        Players can create and destroy various types of blocks in a
                        three-dimensional open world. This allows forming structures in
                        every possible creation, on multiplayer servers or in singleplayer.
+               </p><p xml:lang="de">
+                       Spieler können in einer offenen 3D-Welt viele verschiedene Arten von
+                       Blöcken platzieren und abbauen. Dies erlaubt das Bauen von vielfältigen
+                       Strukturen im Einzelspieler oder auf Mehrspielerservern.
                </p><p>
                        Minetest is designed to be simple, stable, and portable.
                        It is lightweight enough to run on fairly old hardware.
+               </p><p xml:lang="de">
+                       Minetest wurde entworfen, um einfach, stabil und portabel zu sein.
+                       Es ist leichtgewichtig genug, um auf relativ alter Hardware zu laufen.
                </p><p>
                        Minetest has many features, including:
+               </p><p xml:lang="de">
+                       Minetest besitzt viele Features, unter anderem:
                </p>
                <ul>
                        <li>Ability to walk around, dig, and build in a near-infinite voxel world</li>
+                       <li xml:lang="de">Die Möglichkeit, in einer nahezu unendlichen Voxel-Welt herumzulaufen, zu graben und zu bauen</li>
                        <li>Crafting of items from raw materials</li>
+                       <li xml:lang="de">Fertigen von Items aus Rohmaterialien</li>
                        <li>Fast and able to run on old and slow hardware</li>
+                       <li xml:lang="de">Gute Performance selbst auf älterer und langsamer Hardware</li>
                        <li>A simple modding API that supports many additions and modifications to the game</li>
+                       <li xml:lang="de">Eine einfache Modding-API, die viele Ergänzungen und Änderungen am Spiel unterstützt</li>
                        <li>Multiplayer support via servers hosted by users</li>
+                       <li xml:lang="de">Mehrspieler auf selber gehosteten Servern</li>
                        <li>Beautiful lightning-fast map generator</li>
+                       <li xml:lang="de">Wunderschöner, blitzschneller Kartengenerator</li>
                </ul>
        </description>
        <screenshots>
@@ -62,6 +80,6 @@
        <translation type="gettext">minetest</translation>
        <update_contact>sfan5@live.de</update_contact>
        <releases>
-               <release date="2021-02-23" version="5.4.0"/>
+               <release date="2022-01-30" version="5.5.0"/>
        </releases>
 </component>
index e105fbd1a1e89309648028bb29966220de22949b..e14b7539e399f05d27d9d86c3fcfc9ae2ae435f2 100644 (file)
@@ -1,4 +1,10 @@
+You can use the content tab in the main menu
+
+ OR
+
 You can install Minetest mods by copying (and extracting) them into this folder.
 To enable them, go to the configure world window in the main menu or write
+
   load_mod_<modname> = true
-in world.mt in the world directory.
+
+in world.mt in the world directory. 
index b7e68188182e34a7c46995794e921521129e45cb..fc4891024b568748deb5156a6214e50270de634d 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-03-19 20:18+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-12-05 13:51+0000\n"
 "Last-Translator: abidin toumi <abidin24@disroot.org>\n"
 "Language-Team: Arabic <https://hosted.weblate.org/projects/minetest/minetest/"
 "ar/>\n"
@@ -18,46 +18,43 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
 "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.10-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "امسح طابور الرسائل الصادرة"
 
 #: builtin/client/chatcommands.lua
 msgid "Empty command."
-msgstr ""
+msgstr "أمر فارغ."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "اخرج للقائمة"
+msgstr "اخرج للقائمة الرئيسة"
 
 #: builtin/client/chatcommands.lua
 msgid "Invalid command: "
-msgstr ""
+msgstr "أمر غير صالح: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
 msgstr ""
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Ù\84اعب Ù\85Ù\86Ù\81رد"
+msgstr "Ù\82ائÙ\85Ø© Ø§Ù\84Ù\84اعبÙ\8aÙ\86 Ø§Ù\84Ù\85تصÙ\84Ù\8aÙ\86"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "لاعب منفرد"
+msgstr "اللاعبون المتصلون: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "طابور الرسائل الصادرة فارغ."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "هذا الأمر معطل من الخادم."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -67,40 +64,40 @@ msgstr "أعِد الإحياء"
 msgid "You died"
 msgstr "مِت"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "مِت"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
-msgstr ""
+msgstr "الأوامر المتوفرة:"
 
 #: builtin/common/chatcommands.lua
 msgid "Available commands: "
-msgstr ""
+msgstr "الأوامر المتاحة: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "الأوامر غير المتاحة: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "احصل على تعليمات الأوامر"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"استخدم '.help <cmd>' للحصول على مزيد من المعلومات أو '.help all' لعرض كل شيء."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "موافق"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<ليس متاحًا>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "حدث خطأ في برنامج Lua النصي:"
@@ -236,7 +233,7 @@ msgstr "الاعتماديتان \"$1\" و $2 ستثبتان."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1 بواسطة $2"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
@@ -256,7 +253,7 @@ msgstr "يحتاج $1 لكن لم يُعثر عليها."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
-msgstr ""
+msgstr "$1 سيُثبت، واعتماديات $1 ستُتجاهل."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "All packages"
@@ -272,7 +269,7 @@ msgstr "عُد للقائمة الرئيسة"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Base Game:"
-msgstr "اللعبة القاعدية"
+msgstr "اللعبة القاعدية :"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
@@ -303,6 +300,11 @@ msgstr "ثبت $1"
 msgid "Install missing dependencies"
 msgstr "ثبت الإعتماديات المفقودة"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "يثبت: نوع الملف \"$1\" غير مدعوم أو هو أرشيف تالف"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -354,7 +356,7 @@ msgstr "حدِّث الكل [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "اعرض مزيدًا من المعلومات عبر المتصفح"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
@@ -382,11 +384,11 @@ msgstr "مواطن بيئية"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Caverns"
-msgstr "Ù\85غارات"
+msgstr "Ù\83Ù\87Ù\88Ù\81"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Caves"
-msgstr "Ù\83Ù\87Ù\88Ù\81"
+msgstr "Ù\85غارات"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Create"
@@ -470,7 +472,7 @@ msgstr "تدفق الطين"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Network of tunnels and caves"
-msgstr "شبÙ\83Ø© Ø£Ù\86Ù\81اÙ\82 Ù\88Ù\83Ù\87Ù\88Ù\81"
+msgstr "شبÙ\83Ø© Ø£Ù\86Ù\81اÙ\82 Ù\88Ù\85غارات"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "No game selected"
@@ -630,7 +632,7 @@ msgstr "المُعادل"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 #, fuzzy
-msgid "Persistance"
+msgid "Persistence"
 msgstr "استمرار"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -741,14 +743,6 @@ msgstr "تثبيت تعديل: لا يمكن ايجاد الاسم الحقيق
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "تثبيت تعديل: لا يمكن العصور على اسم مجلد مناسب لحزمة التعديلات $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "يثبت: نوع الملف \"$1\" غير مدعوم أو هو أرشيف تالف"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "ثبت: الملف: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "فشل إيجاد تعديل أو حزمة تعديلات صالحة"
@@ -783,7 +777,7 @@ msgstr "جرب إعادة تمكين قائمة الحوادم العامة وت
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "حول"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
@@ -791,7 +785,7 @@ msgstr "المساهمون النشطون"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active renderer:"
-msgstr ""
+msgstr "محرك التصيير النشط:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -927,9 +921,8 @@ msgid "Start Game"
 msgstr "ابدأ اللعبة"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- العنوان: "
+msgstr "عنوان"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -945,22 +938,20 @@ msgstr "النمط الإبداعي"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "- التضرر: "
+msgstr "الضرر / قتال اللاعبين"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "حذف المفضلة"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "المفضلة"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "خوادم غير متوافقة"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -971,18 +962,16 @@ msgid "Ping"
 msgstr ""
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "أعÙ\84Ù\86 Ø¹Ù\86 Ø§Ù\84خادÙ\88Ù\85"
+msgstr "Ø®Ù\88ادÙ\85 Ø¹Ù\85Ù\88Ù\85Ù\8aØ©"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "حدِّث"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Ù\85Ù\86Ù\81Ø° Ø§Ù\84خدÙ\88م"
+msgstr "Ù\88صÙ\81 Ø§Ù\84خادم"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1026,11 +1015,11 @@ msgstr "زجاج متصل"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "ظلال ديناميكية"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "ظلال ديناميكية: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1038,7 +1027,7 @@ msgstr "اوراق بتفاصيل واضحة"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "عالي"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
@@ -1046,7 +1035,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "متوسط"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1120,10 +1109,6 @@ msgstr "إضاءة سلسة"
 msgid "Texturing:"
 msgstr "الإكساء:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "لاستخدام المظللات يجب استخدام تعريف OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1138,11 +1123,11 @@ msgstr "مرشح خطي ثلاثي"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "عالية جدا"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "منخفضة جدًا"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1156,7 +1141,7 @@ msgstr "سوائل متموجة"
 msgid "Waving Plants"
 msgstr "نباتات متموجة"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "انتهت مهلة الاتصال."
 
@@ -1185,8 +1170,8 @@ msgid "Connection error (timed out?)"
 msgstr "خطأ في الاتصال (انتهاء المهلة؟)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "لا يمكن إيجاد أو تحميل لعبة \""
+msgid "Could not find or load game"
+msgstr "تعذر العثور على اللعبة أو تحميلها "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1228,14 +1213,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- العنوان: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- النمط الإبداعي: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- التضرر: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- النمط: "
@@ -1257,6 +1234,16 @@ msgstr "- قتال اللاعبين: "
 msgid "- Server Name: "
 msgstr "- اسم الخادم: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "حدث خطأ في التسلسل:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "رُفض النفاذ. السبب: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "المشي التلقائي معطل"
@@ -1265,6 +1252,22 @@ msgstr "المشي التلقائي معطل"
 msgid "Automatic forward enabled"
 msgstr "المشي التلقائي ممكن"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "حدود الكتل مخفية"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "حدود كل الكتل ظاهرة"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "حدود الكتلة الحالية ظاهرة"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "حدود الكتل القريبة ظاهرة"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "تحديث الكاميرا معطل"
@@ -1273,6 +1276,10 @@ msgstr "تحديث الكاميرا معطل"
 msgid "Camera update enabled"
 msgstr "تحديث الكاميرا مفعل"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "تعذر إظهار حدود الكتل ( تحتاج امتياز 'basic_debug')"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "غير كلمة المرور"
@@ -1285,6 +1292,10 @@ msgstr "الوضع السينمائي معطل"
 msgid "Cinematic mode enabled"
 msgstr "الوضع السينمائي مفعل"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "فُصل الاتصال عن العميل"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "البرمجة النصية معطلة من جانب العميل"
@@ -1293,6 +1304,10 @@ msgstr "البرمجة النصية معطلة من جانب العميل"
 msgid "Connecting to server..."
 msgstr "يتصل بالخادوم…"
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "فشل الاتصال لسبب مجهول"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "تابع"
@@ -1330,6 +1345,11 @@ msgstr ""
 "- عجلة الفأرة: غيير العنصر\n"
 "- -%s: دردشة\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "تعذر تحليل العنوان:%s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "ينشىء عميلا…"
@@ -1459,9 +1479,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "الخريطة المصغرة معطلة من قبل لعبة أو تعديل"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Ù\84اعب Ù\85Ù\86Ù\81رد"
+msgstr "Ù\85تعدد Ø§Ù\84Ù\84اعبÙ\8aÙ\86"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1535,6 +1554,21 @@ msgstr "نظام الصوت غير مدمج أثناء البناء"
 msgid "Sound unmuted"
 msgstr "الصوت غير مكتوم"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "يُحتمل أن نسخة الخادم مختلفة عن %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "تعذر الاتصال بـ %s لأن IPv6 معطلة"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1605,9 +1639,8 @@ msgid "Caps Lock"
 msgstr "Caps Lock"
 
 #: src/client/keycode.cpp
-#, fuzzy
 msgid "Control"
-msgstr "Control"
+msgstr "التحكم"
 
 #: src/client/keycode.cpp
 msgid "Down"
@@ -1623,17 +1656,15 @@ msgstr ""
 
 #: src/client/keycode.cpp
 msgid "Execute"
-msgstr ""
+msgstr "شغّل"
 
 #: src/client/keycode.cpp
-#, fuzzy
 msgid "Help"
-msgstr "Help"
+msgstr "مساعدة"
 
 #: src/client/keycode.cpp
-#, fuzzy
 msgid "Home"
-msgstr "Home"
+msgstr "الرئيسية"
 
 #: src/client/keycode.cpp
 #, fuzzy
@@ -1906,19 +1937,26 @@ msgid "Minimap hidden"
 msgstr "الخريطة المصغرة مخفية"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in radar mode, Zoom x%d"
-msgstr "الخريطة المصغرة في وضع الرادار، تكبير x1"
+msgstr "الخريطة المصغرة في وضع الرادار، تكبير x%d"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in surface mode, Zoom x%d"
-msgstr "الخريطة المصغرة في وضع الأسطح، تكبير x1"
+msgstr "الخريطة المصغرة في وضع الأسطح، تكبير x%d"
 
 #: src/client/minimap.cpp
-#, fuzzy
 msgid "Minimap in texture mode"
-msgstr "الخريطة المصغرة في وضع الأسطح، تكبير x1"
+msgstr "الخريطة المصغرة في وضع الاكساء"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "فشل فتح صفحة الويب"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "يفتح صفحة الويب"
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
@@ -1946,9 +1984,8 @@ msgid "Proceed"
 msgstr "تابع"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"خاص\" = التسلق نزولا"
+msgstr "\"Aux1\" = التسلق نزولا"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1960,7 +1997,7 @@ msgstr "القفز التلقائي"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1968,7 +2005,7 @@ msgstr "للخلف"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "حدود الكتلة"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -1988,11 +2025,11 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. range"
-msgstr ""
+msgstr "قلل المدى"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. volume"
-msgstr ""
+msgstr "قلل الحجم"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Double tap \"jump\" to toggle fly"
@@ -2008,11 +2045,11 @@ msgstr "للأمام"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. range"
-msgstr ""
+msgstr "زد المدى"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. volume"
-msgstr ""
+msgstr "زد الحجم"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inventory"
@@ -2056,7 +2093,7 @@ msgstr "صوّر الشاشة"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Sneak"
-msgstr ""
+msgstr "تسلل"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle HUD"
@@ -2119,8 +2156,9 @@ msgid "Muted"
 msgstr "مكتوم"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "حجم الصوت: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "حجم الصوت: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2203,11 +2241,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "3D clouds"
-msgstr ""
+msgstr "سحب ثلاثية الأبعاد"
 
 #: src/settings_translation_file.cpp
 msgid "3D mode"
-msgstr ""
+msgstr "وضع الشاشة ثلاثية الأبعاد"
 
 #: src/settings_translation_file.cpp
 msgid "3D mode parallax strength"
@@ -2269,7 +2307,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server crashes."
-msgstr ""
+msgstr "رسالة ستعرض عند انهيار الخادم."
 
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server shuts down."
@@ -2289,23 +2327,23 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration in air"
-msgstr ""
+msgstr "تسارع الطيران"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration of gravity, in nodes per second per second."
-msgstr ""
+msgstr "تسارع الجاذبية، عقدة/ثانية²."
 
 #: src/settings_translation_file.cpp
 msgid "Active Block Modifiers"
-msgstr ""
+msgstr "معدِلات الكتل النشطة"
 
 #: src/settings_translation_file.cpp
 msgid "Active block management interval"
-msgstr ""
+msgstr "مهلة إدارة الكتل النشطة"
 
 #: src/settings_translation_file.cpp
 msgid "Active block range"
-msgstr ""
+msgstr "مدى الكتل النشطة"
 
 #: src/settings_translation_file.cpp
 msgid "Active object send range"
@@ -2317,6 +2355,10 @@ msgid ""
 "Leave this blank to start a local server.\n"
 "Note that the address field in the main menu overrides this setting."
 msgstr ""
+"عنوان الخادم\n"
+"اتركه فارغًا لاستضافة لعبة محلية.\n"
+"أدرك أن هذه القيمة ستُتجاوز إذا كان حقل العنوان في القائمة الرئيسية يحوي "
+"عنوانًا."
 
 #: src/settings_translation_file.cpp
 msgid "Adds particles when digging a node."
@@ -2328,6 +2370,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2340,9 +2386,10 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
-msgstr ""
+msgstr "متقدم"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Alters the light curve by applying 'gamma correction' to it.\n"
 "Higher values make middle and lower light levels brighter.\n"
@@ -2350,6 +2397,11 @@ msgid ""
 "This only has significant effect on daylight and artificial\n"
 "light, it has very little effect on natural night light."
 msgstr ""
+"يعدل منحنى الضوء عن طريق تطبيق \"تصحيح جاما\" عليه.\n"
+"القيم الأعلى تجعل مستويات الإضاءة المتوسطة والدنيا أكثر بريقًا.\n"
+"تترك القيمة \"1.0\" منحنى الضوء على حاله.\n"
+"لها تأثير كبير فقط على ضوء النهار والضوء الصناعي ، ولها تأثير ضئيل للغاية "
+"على ضوء الليل الطبيعي."
 
 #: src/settings_translation_file.cpp
 msgid "Always fly and fast"
@@ -2361,11 +2413,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Amount of messages a player may send per 10 seconds."
-msgstr ""
+msgstr "عدد اارسائل المسموح بها لكل 10 ثوان."
 
 #: src/settings_translation_file.cpp
 msgid "Amplifies the valleys."
-msgstr ""
+msgstr "تضخيم الوديان."
 
 #: src/settings_translation_file.cpp
 msgid "Anisotropic filtering"
@@ -2373,15 +2425,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Announce server"
-msgstr ""
+msgstr "أعلن عن الخادم"
 
 #: src/settings_translation_file.cpp
 msgid "Announce to this serverlist."
-msgstr ""
+msgstr "أدرجه في هذه القائمة."
 
 #: src/settings_translation_file.cpp
 msgid "Append item name"
-msgstr ""
+msgstr "ضمّن اسم العنصر"
 
 #: src/settings_translation_file.cpp
 msgid "Append item name to tooltip."
@@ -2403,7 +2455,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Ask to reconnect after crash"
-msgstr ""
+msgstr "اطلب إعادة الاتصال بعد انقطاعه"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2422,11 +2474,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Automatic forward key"
-msgstr ""
+msgstr "زر المشي التلقائي"
 
 #: src/settings_translation_file.cpp
 msgid "Automatically jump up single-node obstacles."
-msgstr ""
+msgstr "قفز تلقائي فوق العوائق التي ارتفاعها كتلة واحدة."
 
 #: src/settings_translation_file.cpp
 msgid "Automatically report to the serverlist."
@@ -2434,7 +2486,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Autosave screen size"
-msgstr ""
+msgstr "حفظ حجم الشاشة تلقائيًا"
 
 #: src/settings_translation_file.cpp
 msgid "Autoscaling mode"
@@ -2442,11 +2494,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Aux1 key"
-msgstr ""
+msgstr "مفتاح Aux1"
 
 #: src/settings_translation_file.cpp
 msgid "Aux1 key for climbing/descending"
-msgstr ""
+msgstr "مفتاح Aux1 للتسلق / للنزول"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2454,19 +2506,19 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Base ground level"
-msgstr ""
+msgstr "مستوى الأرض الأساسي"
 
 #: src/settings_translation_file.cpp
 msgid "Base terrain height."
-msgstr ""
+msgstr "إرتفاع التضاريس الأساسي."
 
 #: src/settings_translation_file.cpp
 msgid "Basic"
-msgstr ""
+msgstr "أساسي"
 
 #: src/settings_translation_file.cpp
 msgid "Basic privileges"
-msgstr ""
+msgstr "الإمتيازات الأساسية"
 
 #: src/settings_translation_file.cpp
 msgid "Beach noise"
@@ -2478,7 +2530,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Bilinear filtering"
-msgstr ""
+msgstr "ترشيح خطي ثنائي"
 
 #: src/settings_translation_file.cpp
 msgid "Bind address"
@@ -2498,27 +2550,27 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Bold and italic font path"
-msgstr ""
+msgstr "مسار الخطين العريض والمائل"
 
 #: src/settings_translation_file.cpp
 msgid "Bold and italic monospace font path"
-msgstr ""
+msgstr "مسار خطي monospace العريض والمائل"
 
 #: src/settings_translation_file.cpp
 msgid "Bold font path"
-msgstr ""
+msgstr "مسار الخط العريض"
 
 #: src/settings_translation_file.cpp
 msgid "Bold monospace font path"
-msgstr ""
+msgstr "مسار خط monospace العريض"
 
 #: src/settings_translation_file.cpp
 msgid "Build inside player"
-msgstr ""
+msgstr "ضع الكتلة في موقع اللاعب"
 
 #: src/settings_translation_file.cpp
 msgid "Builtin"
-msgstr ""
+msgstr "مدمج"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2530,11 +2582,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Camera smoothing"
-msgstr ""
+msgstr "انسيابية حركة الكامير"
 
 #: src/settings_translation_file.cpp
 msgid "Camera smoothing in cinematic mode"
-msgstr ""
+msgstr "انسيابية حركة الكامير في الوضع السنيمائي"
 
 #: src/settings_translation_file.cpp
 msgid "Camera update toggle key"
@@ -2554,7 +2606,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Cave width"
-msgstr ""
+msgstr "عُرض المغارة"
 
 #: src/settings_translation_file.cpp
 msgid "Cave1 noise"
@@ -2594,13 +2646,18 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "الأوامر"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
-msgstr ""
+msgstr "حجم خط المحادثة"
 
 #: src/settings_translation_file.cpp
 msgid "Chat key"
-msgstr ""
+msgstr "مفتاح المحادثة"
 
 #: src/settings_translation_file.cpp
 msgid "Chat log level"
@@ -2608,11 +2665,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chat message count limit"
-msgstr ""
+msgstr "حدُّ رسائل المحادثة"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message format"
-msgstr ""
+msgstr "نسقُ رسائل المحادثة"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message kick threshold"
@@ -2620,15 +2677,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chat message max length"
-msgstr ""
+msgstr "الطول الأقصى لرسائل المحادثة"
 
 #: src/settings_translation_file.cpp
 msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+msgid "Chat weblinks"
+msgstr "روابط المحادثة"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2636,23 +2693,31 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Cinematic mode"
-msgstr ""
+msgstr "الوضع السنيمائي"
 
 #: src/settings_translation_file.cpp
 msgid "Cinematic mode key"
-msgstr ""
+msgstr "مفتاح الوضع السنيمائي"
 
 #: src/settings_translation_file.cpp
 msgid "Clean transparent textures"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Client"
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
 msgstr ""
+"روابط ويب قابلة للنقر (زر الفأرة الأوسط أو زر الفأرة الأيسر+Ctrl) مفعلة في "
+"المحادثة."
+
+#: src/settings_translation_file.cpp
+msgid "Client"
+msgstr "عميل"
 
 #: src/settings_translation_file.cpp
 msgid "Client and Server"
-msgstr ""
+msgstr "عميل وخادم"
 
 #: src/settings_translation_file.cpp
 msgid "Client modding"
@@ -2668,15 +2733,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Climbing speed"
-msgstr ""
+msgstr "سرعة التسلق"
 
 #: src/settings_translation_file.cpp
 msgid "Cloud radius"
-msgstr ""
+msgstr "تفاصيل السحاب"
 
 #: src/settings_translation_file.cpp
 msgid "Clouds"
-msgstr ""
+msgstr "سحاب"
 
 #: src/settings_translation_file.cpp
 msgid "Clouds are a client side effect."
@@ -2684,15 +2749,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Clouds in menu"
-msgstr ""
+msgstr "سحب في القائمة"
 
 #: src/settings_translation_file.cpp
 msgid "Colored fog"
-msgstr ""
+msgstr "ضباب ملون"
 
 #: src/settings_translation_file.cpp
 msgid "Colored shadows"
-msgstr ""
+msgstr "ظلال ملونة"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2722,16 +2787,40 @@ msgid "Command key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Connect glass"
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
 msgstr ""
+"مستوى ضغط لحفظ الملف mapblocks في القرص.\n"
+"-1 - المستوى الافتراضي\n"
+"0 - ضغط ضعيف، سريع\n"
+"9 - ضغط قوي، بطيء"
 
 #: src/settings_translation_file.cpp
-msgid "Connect to external media server"
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
 msgstr ""
+"مستوى ضغط لإرسال ملف mapblocks للعميل.\n"
+"-1 - المستوى الافتراضي\n"
+"0 - ضغط ضعيف، سريع\n"
+"9 - ضغط قوي، بطيء"
+
+#: src/settings_translation_file.cpp
+msgid "Connect glass"
+msgstr "زجاج متصل"
+
+#: src/settings_translation_file.cpp
+msgid "Connect to external media server"
+msgstr "اتصل بخادم وسائط خارجي"
 
 #: src/settings_translation_file.cpp
 msgid "Connects glass if supported by node."
-msgstr ""
+msgstr "زجاج متصل اذا كانت العقدة تدعمه."
 
 #: src/settings_translation_file.cpp
 msgid "Console alpha"
@@ -2769,7 +2858,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Controls"
-msgstr ""
+msgstr "التحكم"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2777,6 +2866,9 @@ msgid ""
 "Examples:\n"
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
+"يتحكم في طول دورة النهار والليل.\n"
+"أمثلة:\n"
+"72 = 20 دقيقة ، 360 = 4 دقائق ، 1 = 24 ساعة ، 0 = نهار / ليل أبدي."
 
 #: src/settings_translation_file.cpp
 msgid "Controls sinking speed in liquid."
@@ -2799,11 +2891,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
-msgstr ""
+msgstr "رسالة الانهيار"
 
 #: src/settings_translation_file.cpp
 msgid "Creative"
-msgstr ""
+msgstr "إبداعي"
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair alpha"
@@ -2812,7 +2904,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2831,7 +2923,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Damage"
-msgstr ""
+msgstr "ضرر"
 
 #: src/settings_translation_file.cpp
 msgid "Debug info toggle key"
@@ -2847,11 +2939,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Dec. volume key"
-msgstr ""
+msgstr "مفتاح تقليل الحجم"
 
 #: src/settings_translation_file.cpp
 msgid "Decrease this to increase liquid resistance to movement."
-msgstr ""
+msgstr "قلل منه لزيادة مقاومة الحركة في السوائل."
 
 #: src/settings_translation_file.cpp
 msgid "Dedicated server step"
@@ -2859,60 +2951,62 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Default acceleration"
-msgstr ""
+msgstr "التسارع الافتراضي"
 
 #: src/settings_translation_file.cpp
 msgid "Default game"
-msgstr ""
+msgstr "اللعبة الافتراضية"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Default game when creating a new world.\n"
 "This will be overridden when creating a world from the main menu."
 msgstr ""
+"اللعبة الافتراضية عند إنشاء عالم جديد.\n"
+"سيُتجاوز هذا الخيار عند إنشاء عالم جديد من القائمة."
 
 #: src/settings_translation_file.cpp
 msgid "Default password"
-msgstr ""
+msgstr "كلمة المرور الافتراضية"
 
 #: src/settings_translation_file.cpp
 msgid "Default privileges"
-msgstr ""
+msgstr "الامتيازات الافتراضية"
 
 #: src/settings_translation_file.cpp
 msgid "Default report format"
-msgstr ""
+msgstr "نسقُ التقارير الافتراضي"
 
 #: src/settings_translation_file.cpp
 msgid "Default stack size"
-msgstr ""
+msgstr "حجم المكدس الافتراضي"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
-msgstr ""
+msgstr "يحدد المناطق التي تتواجد بها أشجار التفاح."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas with sandy beaches."
-msgstr ""
+msgstr "يحدد المناطق التي توجد بها شواطئ رملية."
 
 #: src/settings_translation_file.cpp
 msgid "Defines distribution of higher terrain and steepness of cliffs."
-msgstr ""
+msgstr "يحدد توزع التضاريس العالية والمنحدرات."
 
 #: src/settings_translation_file.cpp
 msgid "Defines distribution of higher terrain."
-msgstr ""
+msgstr "يحدد توزع التضاريس العالية."
 
 #: src/settings_translation_file.cpp
 msgid "Defines full size of caverns, smaller values create larger caverns."
-msgstr ""
+msgstr "يضبط حجم الكهوف ، كلما قلت القيمة زاد حجم الكهوف."
 
 #: src/settings_translation_file.cpp
 msgid "Defines large-scale river channel structure."
@@ -2920,15 +3014,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Defines location and terrain of optional hills and lakes."
-msgstr ""
+msgstr "يحدد تضاريس التلال والبحيرات الاختيارية وموقعها."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the base ground level."
-msgstr ""
+msgstr "يحدد مستوى الأرض الأساسي."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the depth of the river channel."
-msgstr ""
+msgstr "يحدد عمق الأنهار."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
@@ -2944,7 +3038,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Defines tree areas and tree density."
-msgstr ""
+msgstr "يحدد مواقع الأشجار وكثافتها."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2954,19 +3048,20 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Delay in sending blocks after building"
-msgstr ""
+msgstr "تأخير إرسال الكتل بعد البناء"
 
 #: src/settings_translation_file.cpp
 msgid "Delay showing tooltips, stated in milliseconds."
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Deprecated Lua API handling"
-msgstr ""
+msgstr "معالجة API Lua القديمة"
 
 #: src/settings_translation_file.cpp
 msgid "Depth below which you'll find giant caverns."
-msgstr ""
+msgstr "بُعد الكهوف الكبيرة عن السطح."
 
 #: src/settings_translation_file.cpp
 msgid "Depth below which you'll find large caves."
@@ -3008,6 +3103,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3054,7 +3153,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3082,13 +3188,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3173,6 +3272,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3270,7 +3375,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
-msgstr ""
+msgstr "الترشيح"
 
 #: src/settings_translation_file.cpp
 msgid "First of 4 2D noises that together define hill/mountain range height."
@@ -3286,11 +3391,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Fixed virtual joystick"
-msgstr ""
+msgstr "عصا التحكم الافتراضية ثابتة"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland density"
-msgstr ""
+msgstr "كثافة الأرض الطافية"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland maximum Y"
@@ -3318,7 +3423,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Fly key"
-msgstr ""
+msgstr "زر الطيران"
 
 #: src/settings_translation_file.cpp
 msgid "Flying"
@@ -3326,27 +3431,27 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Fog"
-msgstr ""
+msgstr "الضباب"
 
 #: src/settings_translation_file.cpp
 msgid "Fog start"
-msgstr ""
+msgstr "بداية الضباب"
 
 #: src/settings_translation_file.cpp
 msgid "Fog toggle key"
-msgstr ""
+msgstr "مفتاح تبديل ظهور الضباب"
 
 #: src/settings_translation_file.cpp
 msgid "Font bold by default"
-msgstr ""
+msgstr "الخط عريض افتراضيًا"
 
 #: src/settings_translation_file.cpp
 msgid "Font italic by default"
-msgstr ""
+msgstr "الخط مائل افتراضيًا"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow"
-msgstr ""
+msgstr "ظل الخط"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow alpha"
@@ -3354,14 +3459,18 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Font size"
+msgstr "حجم الخط"
+
+#: src/settings_translation_file.cpp
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3370,6 +3479,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3429,10 +3549,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3481,7 +3597,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3595,154 +3711,160 @@ msgid ""
 "Horizontal acceleration in air when jumping or falling,\n"
 "in nodes per second per second."
 msgstr ""
+"التسارع الأفقي عند الصقوط والقفز،\n"
+"وحدتها عقدة/ثانية²."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Horizontal and vertical acceleration in fast mode,\n"
 "in nodes per second per second."
 msgstr ""
+"التسارع الأفقي والعمودي في نمط السرعة،\n"
+"وحدتها عقدة/ثانية²."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Horizontal and vertical acceleration on ground or when climbing,\n"
 "in nodes per second per second."
 msgstr ""
+"التسارع الأفقي والعمودي أثناء التسلق،\n"
+"وحدتها عقدة/ثانية²."
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar next key"
-msgstr ""
+msgstr "مفتاح العنصر التالي في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar previous key"
-msgstr ""
+msgstr "مفتاح العنصر السابق في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 1 key"
-msgstr ""
+msgstr "مفتاح الخانة 1 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 10 key"
-msgstr ""
+msgstr "مفتاح الخانة 10 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 11 key"
-msgstr ""
+msgstr "مفتاح الخانة 11 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 12 key"
-msgstr ""
+msgstr "مفتاح الخانة 21 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 13 key"
-msgstr ""
+msgstr "مفتاح الخانة 13 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 14 key"
-msgstr ""
+msgstr "مفتاح الخانة 14 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 15 key"
-msgstr ""
+msgstr "مفتاح الخانة 15 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 16 key"
-msgstr ""
+msgstr "مفتاح الخانة 16 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 17 key"
-msgstr ""
+msgstr "مفتاح الخانة 17 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 18 key"
-msgstr ""
+msgstr "مفتاح الخانة 18 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 19 key"
-msgstr ""
+msgstr "مفتاح الخانة 19 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 2 key"
-msgstr ""
+msgstr "مفتاح الخانة 2 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 20 key"
-msgstr ""
+msgstr "مفتاح الخانة 20 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 21 key"
-msgstr ""
+msgstr "مفتاح الخانة 21 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 22 key"
-msgstr ""
+msgstr "مفتاح الخانة 22 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 23 key"
-msgstr ""
+msgstr "مفتاح الخانة 23 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 24 key"
-msgstr ""
+msgstr "مفتاح الخانة 24 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 25 key"
-msgstr ""
+msgstr "مفتاح الخانة 25 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 26 key"
-msgstr ""
+msgstr "مفتاح الخانة 26 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 27 key"
-msgstr ""
+msgstr "مفتاح الخانة 27 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 28 key"
-msgstr ""
+msgstr "مفتاح الخانة 28 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 29 key"
-msgstr ""
+msgstr "مفتاح الخانة 29 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 3 key"
-msgstr ""
+msgstr "مفتاح الخانة 3 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 30 key"
-msgstr ""
+msgstr "مفتاح الخانة 30 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 31 key"
-msgstr ""
+msgstr "مفتاح الخانة 31 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 32 key"
-msgstr ""
+msgstr "مفتاح الخانة 32 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 4 key"
-msgstr ""
+msgstr "مفتاح الخانة 4 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 5 key"
-msgstr ""
+msgstr "مفتاح الخانة 5 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 6 key"
-msgstr ""
+msgstr "مفتاح الخانة 6 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 7 key"
-msgstr ""
+msgstr "مفتاح الخانة 7 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 8 key"
-msgstr ""
+msgstr "مفتاح الخانة 8 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 9 key"
-msgstr ""
+msgstr "مفتاح الخانة 9 في شريط الإجراءات"
 
 #: src/settings_translation_file.cpp
 msgid "How deep to make rivers."
@@ -3754,6 +3876,9 @@ msgid ""
 "If negative, liquid waves will move backwards.\n"
 "Requires waving liquids to be enabled."
 msgstr ""
+"سرعة موجات السوائل.كلما زادت القيمة زادت سرعتها.\n"
+"إذا كانت سالبة ، فإن حركة الموجات ستكون لجهة المعاكسة .\n"
+"لاستخدامها فعّل سوائل متموجة."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3775,27 +3900,33 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Humidity variation for biomes."
-msgstr ""
+msgstr "اختلاف الرطوبة في الحيوم."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "IPv6"
-msgstr ""
+msgstr "IPv6"
 
 #: src/settings_translation_file.cpp
 msgid "IPv6 server"
-msgstr ""
+msgstr "خادم IPv6"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "If FPS would go higher than this, limit it by sleeping\n"
 "to not waste CPU power for no benefit."
 msgstr ""
+"إذا كان عدد الإطارات في الثانية (FPS) يتجاوز هذه القيمة\n"
+"حدّه حتى لا تستهلك سرعة المعالج هباءً."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
+"إذا تم تعطيله ، فسيتم استخدام مفتاح \"Aux1\" للطيران بسرعة إذا كانت أوضاع "
+"الطيران والسرعة \n"
+"مفعلة."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3819,6 +3950,8 @@ msgid ""
 "and\n"
 "descending."
 msgstr ""
+"إذا فُعّل ، سيستخدم مفتاح \"Aux1\" بدلاً من مفتاح \"التسلل\" للتحرك للتسلق "
+"والنزول."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3828,7 +3961,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "If enabled, disable cheat prevention in multiplayer."
-msgstr ""
+msgstr "إذا فُعّل، سيعطل مكافحة الغش في وضع تعدد اللاعبين."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3913,7 +4046,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3997,7 +4130,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4567,7 +4700,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Kick players who sent more than X messages per 10 seconds."
-msgstr ""
+msgstr "اطرد اللاعبين الذين أرسلوا أكثر من X رسالة في 10 ثوانٍ."
 
 #: src/settings_translation_file.cpp
 msgid "Lake steepness"
@@ -4579,19 +4712,19 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Language"
-msgstr ""
+msgstr "اللغة"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave depth"
-msgstr ""
+msgstr "عمق المغارات الكبيرة"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave maximum number"
-msgstr ""
+msgstr "أقصى عدد للمغارات الكبيرة"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave minimum number"
-msgstr ""
+msgstr "أقل عدد للمغارات الكبيرة"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave proportion flooded"
@@ -4603,7 +4736,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Leaves style"
-msgstr ""
+msgstr "مظهر الأوراق"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4612,6 +4745,10 @@ msgid ""
 "-   Simple: only outer faces, if defined special_tiles are used\n"
 "-   Opaque: disable transparency"
 msgstr ""
+"مظهر أوراق الشجر:\n"
+"- مفصل: كل الوجوه مرئية\n"
+"- بسيط: الوجوه الخارجية فقط ، إذا تم تحديد \"special_tiles\"\n"
+"- معتم: يعطل الشفافية"
 
 #: src/settings_translation_file.cpp
 msgid "Left key"
@@ -4826,7 +4963,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5119,7 +5256,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5130,6 +5267,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5251,7 +5392,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5275,11 +5416,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5302,17 +5445,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5415,9 +5554,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5710,26 +5849,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5820,8 +5951,9 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
-msgstr ""
+#, fuzzy
+msgid "Show name tag backgrounds by default"
+msgstr "الخط عريض افتراضيًا"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -5925,6 +6057,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6035,7 +6175,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6053,7 +6193,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6122,7 +6262,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6215,6 +6355,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6285,7 +6429,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6468,6 +6612,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6489,7 +6637,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6497,14 +6645,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6630,24 +6771,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6660,6 +6783,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- النمط الإبداعي: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- التضرر: "
+
 #~ msgid "Address / Port"
 #~ msgstr "العنوان \\ المنفذ"
 
@@ -6690,6 +6819,9 @@ msgstr ""
 #~ msgid "Generate Normal Maps"
 #~ msgstr "ولِد خرائط عادية"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "ثبت: الملف: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "الرئيسية"
 
@@ -6729,11 +6861,17 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "إلعب فرديا"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "لاستخدام المظللات يجب استخدام تعريف OpenGL."
+
 #~ msgid "View"
 #~ msgstr "إعرض"
 
 #~ msgid "Yes"
 #~ msgstr "نعم"
 
+#~ msgid "You died."
+#~ msgstr "مِت"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index bfae449addc22bc7ff3681987b19605f5b743e44..d625a7c7525f3517f9c999ea3edd003e1b6adaac 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Belarusian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2019-11-19 23:04+0000\n"
 "Last-Translator: Viktar Vauchkevich <victorenator@gmail.com>\n"
 "Language-Team: Belarusian <https://hosted.weblate.org/projects/minetest/"
@@ -65,11 +65,6 @@ msgstr "Адрадзіцца"
 msgid "You died"
 msgstr "Вы загінулі"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Вы загінулі"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -101,6 +96,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Адбылася памылка ў Lua-скрыпце:"
@@ -307,6 +306,11 @@ msgstr "Усталяваць"
 msgid "Install missing dependencies"
 msgstr "Неабавязковыя залежнасці:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Усталёўка: непадтрымліваемы файл тыпу \"$1\" або сапсаваны архіў"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -653,7 +657,8 @@ msgid "Offset"
 msgstr "Зрух"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Сталасць"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -766,14 +771,6 @@ msgstr ""
 "Усталёўка мадыфікацыі: не атрымалася знайсці прыдатны каталог для пакунка "
 "мадыфікацый \"$1\""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Усталёўка: непадтрымліваемы файл тыпу \"$1\" або сапсаваны архіў"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Усталёўка: файл: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Не атрымалася знайсці прыдатную мадыфікацыю альбо пакунак мадыфікацый"
@@ -1151,10 +1148,6 @@ msgstr "Мяккае асвятленне"
 msgid "Texturing:"
 msgstr "Тэкстураванне:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Для ўключэння шэйдэраў неабходна выкарыстоўваць OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Танальнае адлюстраванне"
@@ -1187,7 +1180,7 @@ msgstr "Калыханне вадкасцяў"
 msgid "Waving Plants"
 msgstr "Дрыготкія расліны"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Таймаут злучэння."
 
@@ -1216,7 +1209,8 @@ msgid "Connection error (timed out?)"
 msgstr "Памылка злучэння (таймаут?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Немагчыма знайсці ці загрузіць гульню \""
 
 #: src/client/clientlauncher.cpp
@@ -1259,14 +1253,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Адрас: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Творчы рэжым: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Пашкоджанні: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Рэжым: "
@@ -1288,6 +1274,16 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Назва сервера: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Адбылася памылка:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Аўтаматычны рух наперад адключаны"
@@ -1296,6 +1292,22 @@ msgstr "Аўтаматычны рух наперад адключаны"
 msgid "Automatic forward enabled"
 msgstr "Аўтаматычны рух наперад уключаны"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Абнаўленне камеры адключана"
@@ -1304,6 +1316,10 @@ msgstr "Абнаўленне камеры адключана"
 msgid "Camera update enabled"
 msgstr "Абнаўленне камеры ўключана"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Змяніць пароль"
@@ -1316,6 +1332,11 @@ msgstr "Кінематаграфічны рэжым адключаны"
 msgid "Cinematic mode enabled"
 msgstr "Кінематаграфічны рэжым уключаны"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Модынг кліента"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Кліентскія мадыфікацыі выключаныя"
@@ -1324,6 +1345,10 @@ msgstr "Кліентскія мадыфікацыі выключаныя"
 msgid "Connecting to server..."
 msgstr "Злучэнне з серверам…"
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Працягнуць"
@@ -1361,6 +1386,11 @@ msgstr ""
 "- Mouse wheel: абраць прадмет\n"
 "- %s: размова\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Стварэнне кліента…"
@@ -1566,6 +1596,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Гук уключаны"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1901,6 +1946,15 @@ msgstr "Мінімапа ў рэжыме паверхні, павелічэнн
 msgid "Minimap in texture mode"
 msgstr "Мінімальны памер тэкстуры"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Не атрымалася спампаваць $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Паролі не супадаюць!"
@@ -2103,7 +2157,8 @@ msgid "Muted"
 msgstr "Сцішаны"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Гучнасць: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2354,6 +2409,10 @@ msgstr ""
 "Наладка DPI (кропак на цалю) на экране\n"
 "(не толькі X11/Android), напрыклад, для 4k-экранаў."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2645,6 +2704,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Максімальная колькасць паведамленняў у размове для выключэння"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Загады размовы"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2680,8 +2744,9 @@ msgid "Chat toggle key"
 msgstr "Клавіша пераключэння размовы"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Загады размовы"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Размова паказваецца"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2699,6 +2764,12 @@ msgstr "Клавіша кінематаграфічнага рэжыму"
 msgid "Clean transparent textures"
 msgstr "Чыстыя празрыстыя тэкстуры"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Кліент"
@@ -2787,6 +2858,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Клавіша загаду"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Суцэльнае шкло"
@@ -2883,7 +2970,7 @@ msgstr "Празрыстасць перакрыжавання"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr "Празрыстасць перакрыжавання (паміж 0 і 255)."
 
 #: src/settings_translation_file.cpp
@@ -2964,8 +3051,8 @@ msgstr "Прадвызначаная гульня"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3094,6 +3181,10 @@ msgstr "Выключыць антычыт"
 msgid "Disallow empty passwords"
 msgstr "Забараніць пустыя паролі"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Даменная назва сервера, што будзе паказвацца ў спісе сервераў."
@@ -3142,7 +3233,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3171,13 +3269,6 @@ msgstr "Уключыць абарону мадыфікацый"
 msgid "Enable players getting damage and dying."
 msgstr "Дазволіць гульцам атрымоўваць пашкоджанні і паміраць."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Уключыць выпадковы карыстальніцкі ўвод (толькі для тэставання)."
@@ -3279,6 +3370,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Інтэрвал друкавання даных прафілявання рухавіка"
@@ -3484,11 +3581,15 @@ msgid "Font size"
 msgstr "Памер шрыфту"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3497,6 +3598,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3561,10 +3673,6 @@ msgstr "Тып фрактала"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Частка бачнай адлегласці, на якой пачынае з'яўляцца туман"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Шрыфты FreeType"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3618,10 +3726,11 @@ msgid "Global callbacks"
 msgstr "Глабальныя зваротныя выклікі"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Глабальныя параметры генерацыі мапы.\n"
 "У генератары мапы 6 параметр «decorations» кіруе ўсімі дэкарацыямі,\n"
@@ -4114,7 +4223,8 @@ msgstr ""
 "Звычайна патрабуюцца толькі распрацоўшчыкам ядра"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Выконваць загады ў размове пры рэгістрацыі."
 
 #: src/settings_translation_file.cpp
@@ -4209,7 +4319,7 @@ msgstr "Інтэрвал паўтору кнопкі джойсціка"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Тып джойсціка"
 
 #: src/settings_translation_file.cpp
@@ -5334,7 +5444,7 @@ msgstr "Інтэрвал захавання мапы"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "Інтэрвал абнаўлення вадкасці"
 
 #: src/settings_translation_file.cpp
@@ -5655,7 +5765,8 @@ msgid "Mod channels"
 msgstr "Каналы мадыфікацый"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "Змяняе памер элеметаў панэлі HUD."
 
 #: src/settings_translation_file.cpp
@@ -5666,6 +5777,11 @@ msgstr "Шлях да монашырыннага шрыфту"
 msgid "Monospace font size"
 msgstr "Памер монашырыннага шрыфту"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Памер монашырыннага шрыфту"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Шум вышыні гор"
@@ -5816,9 +5932,10 @@ msgstr ""
 "'On_generated. Для большасці карыстальнікаў найлепшым значэннем можа быць 1."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Колькасць дадатковых блокаў, што могуць адначасова загружацца загадам /"
@@ -5848,11 +5965,13 @@ msgstr ""
 "Адкрыць меню паўзы калі акно страціла фокус. Не будзе працаваць калі якое-"
 "небудзь меню ўжо адкрыта."
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5877,17 +5996,13 @@ msgstr "Шлях да каталога тэкстур. Усе тэкстуры 
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -6006,9 +6121,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6348,26 +6463,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6480,7 +6587,7 @@ msgstr ""
 "Пасля змены мовы патрэбна перазапусціць гульню."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6607,6 +6714,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid ""
@@ -6727,7 +6842,7 @@ msgstr "Шлях да тэкстур"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6753,7 +6868,7 @@ msgstr "URL рэпазіторыя"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "Ідэнтыфікатар джойсціка для выкарыстання"
 
 #: src/settings_translation_file.cpp
@@ -6840,9 +6955,10 @@ msgstr ""
 "з падтрымкай шэйдэраў."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr "Адчувальнасць восяў джойсціка пры азіранні."
 
 #: src/settings_translation_file.cpp
@@ -6958,6 +7074,10 @@ msgstr "Затрымка падказкі"
 msgid "Touch screen threshold"
 msgstr "Парог сэнсарнага экрана"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Шум дрэў"
@@ -7039,8 +7159,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Выкарыстоўваць білінейную фільтрацыю пры маштабаванні тэкстур."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7244,6 +7365,11 @@ msgstr "Даўжыня водных хваляў"
 msgid "Waving plants"
 msgstr "Калыханне раслін"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Колер вобласці вылучэння"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7273,7 +7399,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7290,19 +7416,9 @@ msgstr ""
 "Таксама выкарыстоўваецца як памер тэкстуры базавага блока для\n"
 "сусветнага аўтамасштабавання тэкстур."
 
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Выкарыстанне шрыфтоў FreeType. Падтрымка FreeType мусіць быць уключаная "
-"падчас кампіляцыі."
-
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7448,24 +7564,6 @@ msgstr "Y-узровень нізкага рэльефу і марскога д
 msgid "Y-level of seabed."
 msgstr "Y-узровень марскога дна."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Таймаўт спампоўвання файла па cURL"
@@ -7479,6 +7577,12 @@ msgstr "Таймаўт cURL"
 msgid "cURL parallel limit"
 msgstr "Ліміт адначасовых злучэнняў cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Творчы рэжым: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Пашкоджанні: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7657,6 +7761,9 @@ msgstr "Ліміт адначасовых злучэнняў cURL"
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "Празрыстасць цені шрыфту (ад 0 да 255)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Шрыфты FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Глыбіня колеру ў поўнаэкранным рэжыме (бітаў на піксель)"
 
@@ -7682,6 +7789,9 @@ msgstr "Ліміт адначасовых злучэнняў cURL"
 #~ "Калі ўключана адначасова з рэжымам палёту, то вызначае напрамак руху "
 #~ "адносна кроку гульца."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Усталёўка: файл: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Глыбіня лавы"
 
@@ -7836,6 +7946,9 @@ msgstr "Ліміт адначасовых злучэнняў cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Гэты шрыфт будзе выкарыстоўваецца для некаторых моў."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Для ўключэння шэйдэраў неабходна выкарыстоўваць OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Кінематаграфічнасць"
 
@@ -7856,6 +7969,15 @@ msgstr "Ліміт адначасовых злучэнняў cURL"
 #~ msgid "Waving water"
 #~ msgstr "Хваляванне вады"
 
+#, fuzzy
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Выкарыстанне шрыфтоў FreeType. Падтрымка FreeType мусіць быць уключаная "
+#~ "падчас кампіляцыі."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Выступ падзямелляў па-над рэльефам."
 
@@ -7871,5 +7993,9 @@ msgstr "Ліміт адначасовых злучэнняў cURL"
 #~ msgid "Yes"
 #~ msgstr "Так"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Вы загінулі"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 4e8037f241cd4d8cfefaf16077ff189699c761c7..fb3a096dc3bf5fe8976c7c1cd17347301339d95e 100644 (file)
@@ -7,9 +7,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2020-08-04 04:41+0000\n"
-"Last-Translator: atomicbeef <teddyg522@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-10 23:53+0000\n"
+"Last-Translator: 109247019824 <stoyan@gmx.com>\n"
 "Language-Team: Bulgarian <https://hosted.weblate.org/projects/minetest/"
 "minetest/bg/>\n"
 "Language: bg\n"
@@ -17,126 +17,126 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Изчистване на изходящата опашка на разговорите"
 
 #: builtin/client/chatcommands.lua
 msgid "Empty command."
-msgstr ""
+msgstr "Празна команда."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Ð\9eбÑ\80аÑ\82но ÐºÑ\8aм Ð\93лавноÑ\82о Ð\9cеню"
+msgstr "Ð\93лавно Ð¼еню"
 
 #: builtin/client/chatcommands.lua
 msgid "Invalid command: "
-msgstr ""
+msgstr "Недействителна команда: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Подадена команда: "
 
 #: builtin/client/chatcommands.lua
 msgid "List online players"
-msgstr ""
+msgstr "Играчи на линия"
 
 #: builtin/client/chatcommands.lua
 msgid "Online players: "
-msgstr ""
+msgstr "Играчи на линия: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Изходящата опашка на разговори е изпразнена."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Командата е забранена от сървъра."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
-msgstr "Прераждането"
+msgstr "Прераждане"
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "You died"
-msgstr "Ти умря"
-
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Ти умря"
+msgstr "Умряхте"
 
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
-msgstr ""
+msgstr "Достъпни команди:"
 
 #: builtin/common/chatcommands.lua
 msgid "Available commands: "
-msgstr ""
+msgstr "Достъпни команди: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Недостъпни команди: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Помощ за командите"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Въведете „.help <cmd>“ за повече информация или „.help all“ за списък с "
+"всички команди."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <команда>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "Добре"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<няма достъпни>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
-msgstr "Ð\98маÑ\88е Ð³Ñ\80еÑ\88ка Ð² Lua Ñ\81кÑ\80ипÑ\82:"
+msgstr "Ð\93Ñ\80еÑ\88ка Ð² Ñ\81кÑ\80ипÑ\82 Ð½Ð° Lua:"
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred:"
-msgstr "Ð\98маÑ\88е грешка:"
+msgstr "Ð\92Ñ\8aзникна грешка:"
 
 #: builtin/fstk/ui.lua
 msgid "Main menu"
-msgstr "Главното меню"
+msgstr "Главно меню"
 
 #: builtin/fstk/ui.lua
 msgid "Reconnect"
-msgstr "Ð\9fовÑ\82аÑ\80Ñ\8fне Ð½Ð° Ð²Ñ\80Ñ\8aзкаÑ\82а"
+msgstr "Ð\9fовÑ\82оÑ\80но Ñ\81вÑ\8aÑ\80зване"
 
 #: builtin/fstk/ui.lua
 msgid "The server has requested a reconnect:"
-msgstr "СÑ\8aÑ\80вÑ\8aÑ\80Ñ\82 Ð¿Ð¾Ð¸Ñ\81ка Ð½Ð¾Ð²Ð° Ð²Ñ\80Ñ\8aзка:"
+msgstr "СÑ\8aÑ\80вÑ\8aÑ\80Ñ\8aÑ\82 Ð¿Ð¾Ð¸Ñ\81ка Ð¿Ð¾Ð²Ñ\82оÑ\80но Ñ\81вÑ\8aÑ\80зване:"
 
 #: builtin/mainmenu/common.lua
 msgid "Protocol version mismatch. "
-msgstr "Ð\92еÑ\80Ñ\81иÑ\8fÑ\82а Ð½Ð° Ð¿Ñ\80оÑ\82окола Ðµ Ð³Ñ\80еÑ\88на. "
+msgstr "Ð\98зданиеÑ\82о Ð½Ð° Ð¿Ñ\80оÑ\82окола Ð½Ðµ Ñ\81Ñ\8aвпада. "
 
 #: builtin/mainmenu/common.lua
 msgid "Server enforces protocol version $1. "
-msgstr "СÑ\8aÑ\80вÑ\8aÑ\80Ñ\82 Ð½Ð°Ð»Ð°Ð³Ð° Ð²ÐµÑ\80Ñ\81иÑ\8f $1 на протокола. "
+msgstr "СÑ\8aÑ\80вÑ\8aÑ\80Ñ\8aÑ\82 Ð½Ð°Ð»Ð°Ð³Ð° Ð¸Ð·Ð´Ð°Ð½Ð¸Ðµ $1 на протокола. "
 
 #: builtin/mainmenu/common.lua
 msgid "Server supports protocol versions between $1 and $2. "
-msgstr "СÑ\8aÑ\80вÑ\8aÑ\80Ñ\8aÑ\82 Ð¿Ð¾Ð´ÐºÑ\80епÑ\8f Ð²ÐµÑ\80Ñ\81ии на протокола между $1 и $2. "
+msgstr "СÑ\8aÑ\80вÑ\8aÑ\80Ñ\8aÑ\82 Ð¿Ð¾Ð´Ð´Ñ\8aÑ\80жа Ð¸Ð·Ð´Ð°Ð½Ð¸Ñ\8fÑ\82а на протокола между $1 и $2. "
 
 #: builtin/mainmenu/common.lua
 msgid "We only support protocol version $1."
-msgstr "Ð\9dие Ñ\81амо Ð¿Ð¾Ð´ÐºÑ\80епÑ\8fме Ð²ÐµÑ\80Ñ\81иÑ\8f $1 на протокола."
+msgstr "Ð\9fоддÑ\8aÑ\80жаме Ñ\81амо Ð¸Ð·Ð´Ð°Ð½Ð¸Ðµ $1 на протокола."
 
 #: builtin/mainmenu/common.lua
 msgid "We support protocol versions between version $1 and $2."
-msgstr "Ð\9dие Ð¿Ð¾Ð´ÐºÑ\80епÑ\8fме Ð²ÐµÑ\80Ñ\81ии на протокола между $1 и $2."
+msgstr "Ð\9fоддÑ\8aÑ\80жаме Ñ\81амо Ð¸Ð·Ð´Ð°Ð½Ð¸Ñ\8fÑ\82а на протокола между $1 и $2."
 
 #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_create_world.lua
@@ -156,35 +156,35 @@ msgstr "Зависимости:"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Disable all"
-msgstr "Ð\94еакÑ\82ивиÑ\80ане Ð½Ð° всички"
+msgstr "Ð\98зклÑ\8eÑ\87ване всички"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Disable modpack"
-msgstr "Ð\94еакÑ\82ивиÑ\80ане Ð½Ð° Ð¼Ð¾Ð´Ð¿Ð°ÐºÐ°"
+msgstr "Ð\98зклÑ\8eÑ\87ване Ð½Ð° Ð¿Ð°ÐºÐµÑ\82 Ñ\81 Ð¼Ð¾Ð´Ð¸Ñ\84икаÑ\86ии"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Enable all"
-msgstr "Ð\90кÑ\82иÑ\80ивÑ\80ане Ð½Ð° всички"
+msgstr "Ð\92клÑ\8eÑ\87ване всички"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Enable modpack"
-msgstr "Ð\90кÑ\82ивиÑ\80ане Ð½Ð° Ð¼Ð¾Ð´Ð¿Ð°ÐºÐ°"
+msgstr "Ð\92клÑ\8eÑ\87ване Ð½Ð° Ð¿Ð°ÐºÐµÑ\82 Ñ\81 Ð¼Ð¾Ð´Ð¸Ñ\84икаÑ\86ии"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid ""
 "Failed to enable mod \"$1\" as it contains disallowed characters. Only "
 "characters [a-z0-9_] are allowed."
 msgstr ""
-"Ð\90кÑ\82ивиÑ\80ане Ð½Ð° Ð¼Ð¾Ð´Ð° \"$1\" Ð±ÐµÑ\88е Ð½ÐµÑ\83Ñ\81пеÑ\88но, Ð·Ð°Ñ\89оÑ\82о Ñ\81Ñ\8aдÑ\8aÑ\80жа Ð·Ð°Ð±Ñ\80анени Ñ\81имволи. "
-"Само символите [a-z0-9_] са разрешени."
+"Ð\92клÑ\8eÑ\87ванеÑ\82о Ð½Ð° Ð¼Ð¾Ð´Ð¸Ñ\84икаÑ\86иÑ\8fÑ\82а â\80\9e$1â\80\9c Ð½Ðµ Ðµ Ñ\83Ñ\81пеÑ\88но, Ð·Ð°Ñ\89оÑ\82о Ñ\81Ñ\8aдÑ\8aÑ\80жа Ð·Ð°Ð±Ñ\80анени "
+"символи. Разрешени са само символите [a-z0-9_]."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Find More Mods"
-msgstr "Ð\9dамиÑ\80ане Ð½Ð° Ð\9eÑ\89е Ð\9cодове"
+msgstr "Ð\9eÑ\89е Ð¼Ð¾Ð´Ð¸Ñ\84икаÑ\86ии"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Mod:"
-msgstr "Мод:"
+msgstr "Модификация:"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No (optional) dependencies"
@@ -192,7 +192,7 @@ msgstr "Няма (незадължителни) зависимости"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No game description provided."
-msgstr "Ð\9dÑ\8fма Ð¾Ð¿Ð¸Ñ\81ание Ð·Ð° Ð¸Ð³Ñ\80аÑ\82а."
+msgstr "Ð\98гÑ\80аÑ\82а Ð½Ñ\8fма Ð¾Ð¿Ð¸Ñ\81ание."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No hard dependencies"
@@ -200,7 +200,7 @@ msgstr "Няма задължителни зависимости"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No modpack description provided."
-msgstr "Ð\9dÑ\8fма Ð¾Ð¿Ð¸Ñ\81ание Ð·Ð° Ð¼Ð¾Ð´Ð¿Ð°ÐºÐ°."
+msgstr "Ð\9fакеÑ\82Ñ\8aÑ\82 Ñ\81 Ð¼Ð¾Ð´Ð¸Ñ\84икаÑ\86ии Ð½Ñ\8fма Ð¾Ð¿Ð¸Ñ\81ание."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No optional dependencies"
@@ -213,7 +213,7 @@ msgstr "Незадължителни зависимости:"
 #: builtin/mainmenu/dlg_config_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp
 msgid "Save"
-msgstr "Ð\97апиÑ\81ване"
+msgstr "Ð\97апазване"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "World:"
@@ -221,38 +221,39 @@ msgstr "Свят:"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "enabled"
-msgstr "Ð\90кÑ\82ивиÑ\80ан"
+msgstr "вклÑ\8eÑ\87ен"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "\"$1\" already exists. Would you like to overwrite it?"
-msgstr ""
+msgstr "„$1“ вече съществува. Да бъде ли презаписан?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
-msgstr ""
+msgstr "$1 и $2 зависимости ще бъдат инсталирани."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1 от $2"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
 "$1 downloading,\n"
 "$2 queued"
 msgstr ""
+"$1 се изтеглят,\n"
+"$2 изчакват"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "$1 downloading..."
-msgstr "Изтегля..."
+msgstr "$1 се изтеглят…"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr ""
+msgstr "$1 задължителни зависимости не могат да бъдат намерени."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
-msgstr ""
+msgstr "$1 ще бъдат инсталирани, а $2 зависимости ще бъдат пропуснати."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "All packages"
@@ -260,27 +261,28 @@ msgstr "Всички пакети"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Already installed"
-msgstr ""
+msgstr "Вече инсталирано"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Back to Main Menu"
-msgstr "Ð\9eбÑ\80аÑ\82но ÐºÑ\8aм Ð\93лавноÑ\82о Ð\9cеню"
+msgstr "Ð\93лавно Ð¼еню"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Base Game:"
-msgstr ""
+msgstr "Основна игра:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
-msgstr "ContentDB не е налично когато Minetest е съставен без cURL"
+msgstr ""
+"Съдържанието от ContentDB не е налично, когато Minetest е компилиран без cURL"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Downloading..."
-msgstr "Изтегля..."
+msgstr "Изтегляне…"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Failed to download $1"
-msgstr "Ð\98зÑ\82еглÑ\8fнеÑ\82о Ð½Ð° $1 Ð±ÐµÑ\88е Ð½ÐµÑ\83Ñ\81пеÑ\88но"
+msgstr "Ð\93Ñ\80еÑ\88ка Ð¿Ñ\80и Ð¸Ð·Ñ\82еглÑ\8fнеÑ\82о Ð½Ð° $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -292,72 +294,73 @@ msgid "Install"
 msgstr "Инсталиране"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install $1"
-msgstr "Инсталиране"
+msgstr "Инсталиране $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install missing dependencies"
-msgstr "Незадължителни зависимости:"
+msgstr "Инсталиране на липсващи зависимости"
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Инсталиране: Неподдържан вид на файл или повреден архив"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
-msgstr "Ð\9cодове"
+msgstr "Ð\9cодиÑ\84икаÑ\86ии"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No packages could be retrieved"
-msgstr "Ð\9fолÑ\83Ñ\87аване Ð½Ð° Ð¿Ð°ÐºÐµÑ\82и Ð±ÐµÑ\88е Ð½ÐµÑ\83Ñ\81пеÑ\88но"
+msgstr "Ð\9fакеÑ\82иÑ\82е Ð½Ðµ Ð¼Ð¾Ð³Ð°Ñ\82 Ð´Ð° Ð±Ñ\8aдаÑ\82 Ð¿Ð¾Ð»Ñ\83Ñ\87ени"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No results"
 msgstr "Няма резултати"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "No updates"
-msgstr "Ð\90кÑ\82Ñ\83ализаÑ\86иÑ\8f"
+msgstr "Ð\9dÑ\8fма Ð¾Ð±Ð½Ð¾Ð²Ñ\8fване"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Not found"
-msgstr ""
+msgstr "Не е намерено"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
-msgstr ""
+msgstr "Презаписване"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Please check that the base game is correct."
-msgstr ""
+msgstr "Уверете се, че основната игра е правилна."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "Изчакващи"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Texture packs"
-msgstr "Пакети на текстури"
+msgstr "Пакети с текстури"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Uninstall"
-msgstr "Ð\94еинÑ\81Ñ\82алиÑ\80ане"
+msgstr "Ð\9fÑ\80емаÑ\85ване"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update"
-msgstr "Ð\90кÑ\82Ñ\83ализаÑ\86иÑ\8f"
+msgstr "Ð\9eбновÑ\8fване"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
-msgstr ""
+msgstr "Обновяване всички [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "Вижте повече в браузъра"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
-msgstr "Ð\92еÑ\87е Ð¸Ð¼Ð° Ñ\81вÑ\8fÑ\82 Ñ\81 Ð¸Ð¼ÐµÑ\82о \"$1\""
+msgstr "СвÑ\8fÑ\82 Ñ\81 Ð¸Ð¼ÐµÑ\82о â\80\9e$1â\80\9c Ð²ÐµÑ\87е Ñ\81Ñ\8aÑ\89еÑ\81Ñ\82вÑ\83ва"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Additional terrain"
@@ -365,23 +368,23 @@ msgstr "Допълнителен терен"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Altitude chill"
-msgstr "СÑ\82Ñ\83д Ð¾Ñ\82 височина"
+msgstr "Ð\97аÑ\81Ñ\82Ñ\83дÑ\8fване Ð²Ñ\8aв височина"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Altitude dry"
-msgstr "СÑ\83Ñ\85 Ð¾Ñ\82 височина"
+msgstr "Ð\97аÑ\81Ñ\83Ñ\88аване Ð²Ñ\8aв височина"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Biome blending"
-msgstr "СмеÑ\81ване Ð¼ÐµÐ¶Ð´Ñ\83 Ð¿Ñ\80иÑ\80одни Ð·Ð¾Ð½и"
+msgstr "СмеÑ\81ване Ð½Ð° Ð±Ð¸Ð¾Ð¼и"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Biomes"
-msgstr "Ð\9fÑ\80иÑ\80одни Ð·Ð¾Ð½и"
+msgstr "Ð\91иоми"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Caverns"
-msgstr "Ð\9fещери"
+msgstr "Ð\93олеми Ð¿ещери"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Caves"
@@ -393,7 +396,7 @@ msgstr "Създаване"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Decorations"
-msgstr "УкÑ\80аÑ\81и"
+msgstr "Ð\94екоÑ\80аÑ\86ии"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download a game, such as Minetest Game, from minetest.net"
@@ -401,7 +404,7 @@ msgstr "Изтегляне на игра, например Minetest Game, от m
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download one from minetest.net"
-msgstr "Ð\98зÑ\82егли ÐµÐ´Ð¸Ð½ от minetest.net"
+msgstr "Ð\98зÑ\82еглеÑ\82е от minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Dungeons"
@@ -413,11 +416,11 @@ msgstr "Равен терен"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floating landmasses in the sky"
-msgstr "Ð\97емни маси в небето"
+msgstr "Ð\9fлаваÑ\89и Ð·емни маси в небето"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floatlands (experimental)"
-msgstr "Ð\97емни Ð¼Ð°Ñ\81и Ð² Ð½ÐµÐ±ÐµÑ\82о (експериментално)"
+msgstr "Ð\9dебеÑ\81ни Ð¾Ñ\81Ñ\82Ñ\80ови (експериментално)"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Game"
@@ -425,11 +428,11 @@ msgstr "Игра"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Generate non-fractal terrain: Oceans and underground"
-msgstr "Създаване на нефрактален терен: Морета и под земята"
+msgstr "Създаване на нефрактален терен: Морета и подземен свят"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Hills"
-msgstr "Ð¥Ñ\8aлми"
+msgstr "Ð¥Ñ\8aлмове"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Humid rivers"
@@ -437,7 +440,7 @@ msgstr "Влажни реки"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Increases humidity around rivers"
-msgstr "Ð\9dаÑ\80аÑ\81Ñ\82ва Ð²Ð»Ð°Ð¶Ð½Ð¾Ñ\81Ñ\82 Ð¾ÐºÐ¾Ð»Ð¾ Ñ\80еки"
+msgstr "УвелиÑ\87ава Ð²Ð»Ð°Ð¶Ð½Ð¾Ñ\81Ñ\82Ñ\82а Ð¾ÐºÐ¾Ð»Ð¾ Ñ\80екиÑ\82е"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Lakes"
@@ -445,19 +448,19 @@ msgstr "Езера"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Low humidity and high heat causes shallow or dry rivers"
-msgstr "Ниска влажност и висока топлина причинява ниски или сухи реки"
+msgstr "Ниската влажност и горещините причиняват плитки или пресъхнали реки"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen"
-msgstr "СÑ\8aздаване Ð½Ð° Ñ\81веÑ\82а"
+msgstr "Ð\93енеÑ\80аÑ\82оÑ\80 Ð½Ð° ÐºÐ°Ñ\80Ñ\82и"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen flags"
-msgstr "Флагове Ð·Ð° Ñ\81Ñ\8aздаване Ð½Ð° Ñ\81веÑ\82а"
+msgstr "Ð\9dаÑ\81Ñ\82Ñ\80ойки Ð½Ð° Ð³ÐµÐ½ÐµÑ\80аÑ\82оÑ\80а"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mapgen-specific flags"
-msgstr "Флагове Ñ\81пеÑ\81иÑ\84иÑ\87ни Ð·Ð° Ñ\81Ñ\8aздване Ð½Ð° Ñ\81веÑ\82а"
+msgstr "СпеÑ\86иÑ\84иÑ\87ни Ð·Ð° Ð³ÐµÐ½ÐµÑ\80аÑ\82оÑ\80а Ð½Ð°Ñ\81Ñ\82Ñ\80ойки"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mountains"
@@ -477,11 +480,11 @@ msgstr "Няма избрана игра"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces heat with altitude"
-msgstr "Намалява топлина с височина"
+msgstr "Намалява топлината във височина"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces humidity with altitude"
-msgstr "Намалява влажност с височина"
+msgstr "Намалява влажността във височина"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Rivers"
@@ -498,35 +501,35 @@ msgstr "Семе"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Smooth transition between biomes"
-msgstr "Ð\93ладка Ð¿Ñ\80омÑ\8fна Ð¼ÐµÐ¶Ð´Ñ\83 Ð¿Ñ\80иÑ\80одни Ð·Ð¾Ð½Ð¸"
+msgstr "Ð\9fлавен Ð¿Ñ\80еÑ\85од Ð¼ÐµÐ¶Ð´Ñ\83 Ð±Ð¸Ð¾Ð¼Ð¸Ñ\82е"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid ""
 "Structures appearing on the terrain (no effect on trees and jungle grass "
 "created by v6)"
 msgstr ""
-"Ð\9fоÑ\8fвÑ\8fване Ð½Ð° Ñ\81Ñ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80и Ð½Ð° Ñ\82еÑ\80ена (нÑ\8fма ÐµÑ\84екÑ\82 Ð½Ð° Ñ\82Ñ\80ева Ð¾Ñ\82 Ð´Ð¶Ñ\83нгла Ð¸ Ð´Ñ\8aÑ\80веÑ\82а "
-"създадени от v6)"
+"СÑ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80и, Ð¿Ð¾Ñ\8fвÑ\8fваÑ\89и Ñ\81е Ð²Ñ\8aÑ\80Ñ\85Ñ\83 Ñ\82еÑ\80ена (нÑ\8fма ÐµÑ\84екÑ\82 Ð²Ñ\8aÑ\80Ñ\85Ñ\83 Ð´Ñ\8aÑ\80веÑ\82аÑ\82а Ð¸ Ñ\82Ñ\80еваÑ\82а Ð² "
+"джунглата, създадени от v6)"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Structures appearing on the terrain, typically trees and plants"
-msgstr "Ð\9fоÑ\8fвÑ\8fване Ð½Ð° Ñ\81Ñ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80и Ð½Ð° Ñ\82еÑ\80ена, Ñ\82ипиÑ\87но дървета и растения"
+msgstr "СÑ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80и, Ð¿Ð¾Ñ\8fвÑ\8fваÑ\89и Ñ\81е Ð²Ñ\8aÑ\80Ñ\85Ñ\83 Ñ\82еÑ\80ена, Ð¾Ð±Ð¸ÐºÐ½Ð¾Ð²Ðµно дървета и растения"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert"
-msgstr "Умерен, Пустиня"
+msgstr "Умерен климат, пустиня"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle"
-msgstr "Умерен, Пустиня, Джунгла"
+msgstr "Умерен климат, пустиня, джунгла"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr "Умерен, Пустиня, Джунгла, Тундра, Тайга"
+msgstr "Умерен климат, пустиня, джунгла, тундра, тайга"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Terrain surface erosion"
-msgstr "Ð\95Ñ\80озиÑ\8f Ð½Ð° Ð¿Ð¾Ð²Ñ\8aÑ\80Ñ\85ноÑ\81Ñ\82 Ð½Ð° Ñ\82еÑ\80ен"
+msgstr "Ð\95Ñ\80озиÑ\8f Ð½Ð° Ð·ÐµÐ¼Ð½Ð°Ñ\82а Ð¿Ð¾Ð²Ñ\8aÑ\80Ñ\85ноÑ\81Ñ\82"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
@@ -534,7 +537,7 @@ msgstr "Трева в джунглата и дървета"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Vary river depth"
-msgstr "Ð\92аÑ\80иÑ\80ане Ð½Ð° Ð´Ñ\8aлбоÑ\87ина Ð½Ð° Ñ\80еки"
+msgstr "Ð\9fÑ\80омÑ\8fна Ð² Ð´Ñ\8aлбоÑ\87инаÑ\82а Ð½Ð° Ñ\80екиÑ\82е"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Very large caverns deep in the underground"
@@ -542,7 +545,7 @@ msgstr "Много големи пещери дълбоко под земята"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Warning: The Development Test is meant for developers."
-msgstr "Внимание: Тестът за Развитие е предназначен за разработници."
+msgstr "Внимание: Тестът за разработка е предназначен за разработчици."
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "World name"
@@ -550,29 +553,29 @@ msgstr "Име на света"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "You have no games installed."
-msgstr "Нямаш инсалирани игри."
+msgstr "Няма инсталирани игри."
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "Are you sure you want to delete \"$1\"?"
-msgstr "СигÑ\83Ñ\80ен Ð»Ð¸ Ñ\81и Ñ\87е Ð¸Ñ\81каÑ\88 Ð´Ð° Ð¸Ð·Ñ\82Ñ\80иваÑ\88 \"$1\"?"
+msgstr "СигÑ\83Ñ\80ни Ð»Ð¸ Ñ\81Ñ\82е, Ñ\87е Ð¸Ñ\81каÑ\82е Ð´Ð° Ð¿Ñ\80емаÑ\85неÑ\82е â\80\9e$1â\80\9c?"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 #: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua
 #: src/client/keycode.cpp
 msgid "Delete"
-msgstr "Ð\98зÑ\82Ñ\80иване"
+msgstr "Ð\9fÑ\80емаÑ\85ване"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: failed to delete \"$1\""
-msgstr "pkgmgr: Ð\98зÑ\82Ñ\80иване Ð½Ð° \"$1\" Ð±ÐµÑ\88е Ð½ÐµÑ\83Ñ\81пеÑ\88но"
+msgstr "pkgmgr: Ð³Ñ\80еÑ\88ка Ð¿Ñ\80и Ð¿Ñ\80емаÑ\85ване Ð½Ð° â\80\9e$1â\80\9c"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: invalid path \"$1\""
-msgstr "pkgmgr: Ð\93Ñ\80еÑ\88на Ð¿Ñ\8aÑ\82ека \"$1\""
+msgstr "pkgmgr: Ð½ÐµÐ´ÐµÐ¹Ñ\81Ñ\82виÑ\82елен Ð¿Ñ\8aÑ\82 â\80\9e$1â\80\9c"
 
 #: builtin/mainmenu/dlg_delete_world.lua
 msgid "Delete World \"$1\"?"
-msgstr "Ð\94а Ð¸Ð·Ñ\82Ñ\80иe Ð»Ð¸ Ñ\81веÑ\82а \"$1\"?"
+msgstr "Ð\9fÑ\80емаÑ\85ване Ð½Ð° Ñ\81веÑ\82а â\80\9e$1â\80\9c?"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid "Accept"
@@ -580,32 +583,31 @@ msgstr "Приемане"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid "Rename Modpack:"
-msgstr "Ð\9fÑ\80еименÑ\83ване Ð½Ð° Ð¼Ð¾Ð´Ð¿Ð°Ðº:"
+msgstr "Ð\9fÑ\80еименÑ\83ване Ð½Ð° Ð¿Ð°ÐºÐµÑ\82 Ð¼Ð¾Ð´Ð¸Ñ\84икаÑ\86ии:"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid ""
 "This modpack has an explicit name given in its modpack.conf which will "
 "override any renaming here."
 msgstr ""
-"Този Ð¼Ð¾Ð´Ð¿Ð°Ðº Ð¸Ð¼Ð° Ð¸Ð·Ñ\80иÑ\87но Ð¸Ð¼Ðµ Ð´Ð°Ð´ÐµÐ½Ð¾ Ð² Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ\8f modpack.conf, ÐºÐ¾ÐµÑ\82о Ñ\89е Ð¾Ñ\82менÑ\8f "
-"вÑ\81Ñ\8fко Ð¿Ñ\80еименÑ\83ване Ñ\82Ñ\83ка."
+"Този Ð¿Ð°ÐºÐµÑ\82 Ñ\81 Ð¼Ð¾Ð´Ð¸Ñ\84икаÑ\86ии Ð¸Ð¼Ð° Ð¸Ð·Ñ\80иÑ\87но Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð¾ Ð¸Ð¼Ðµ Ð² modpack.conf, ÐºÐ¾ÐµÑ\82о Ñ\89е "
+"оÑ\82мени Ð²Ñ\81Ñ\8fко Ð¿Ñ\80еименÑ\83ване."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "(No description of setting given)"
-msgstr ""
+msgstr "(Настройката няма описание)"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "2D Noise"
-msgstr ""
+msgstr "Двуизмерен шум"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "< Back to Settings page"
-msgstr ""
+msgstr "Главно меню"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-#, fuzzy
 msgid "Browse"
-msgstr "Ð\9fÑ\80еглеждане"
+msgstr "Разглеждане"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua
 msgid "Disabled"
@@ -613,7 +615,7 @@ msgstr "Изключено"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Edit"
-msgstr ""
+msgstr "Редактиране"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Enabled"
@@ -621,34 +623,34 @@ msgstr "Включено"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Lacunarity"
-msgstr ""
+msgstr "Лакунарност"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Octaves"
-msgstr ""
+msgstr "Октави"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Offset"
-msgstr "Ð\98зместване"
+msgstr "Ð\9eÑ\82местване"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
-msgstr ""
+#, fuzzy
+msgid "Persistence"
+msgstr "Устойчивост"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid integer."
-msgstr ""
+msgstr "Въведете цяло число."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid number."
-msgstr ""
+msgstr "Въведете число."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Restore Default"
-msgstr ""
+msgstr "По подразбиране"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Scale"
 msgstr "Мащаб"
 
@@ -658,32 +660,31 @@ msgstr "Търсене"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Select directory"
-msgstr ""
+msgstr "Избор на папка"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Select file"
-msgstr ""
+msgstr "Избор на файл"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Show technical names"
-msgstr ""
+msgstr "Технически наименования"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "The value must be at least $1."
-msgstr ""
+msgstr "Стойността трябва да е най-малко $1."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "The value must not be larger than $1."
-msgstr ""
+msgstr "Стойността трябва да е най-много $1."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "X"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-#, fuzzy
 msgid "X spread"
-msgstr "РазпÑ\80оÑ\81Ñ\82Ñ\80анение Ð½Ð° Ð¥-оÑ\81Ñ\82а"
+msgstr "РазпÑ\80еделение Ð¿Ð¾ X"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Y"
@@ -691,7 +692,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Y spread"
-msgstr "РазпÑ\80оÑ\81Ñ\82Ñ\80анение Ð½Ð° Ð£-оÑ\81Ñ\82а"
+msgstr "РазпÑ\80еделение Ð¿Ð¾ Y"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Z"
@@ -699,7 +700,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Z spread"
-msgstr ""
+msgstr "Разпределение по Z"
 
 #. ~ "absvalue" is a noise parameter flag.
 #. It is short for "absolute value".
@@ -714,7 +715,7 @@ msgstr ""
 #. for noise settings in main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "defaults"
-msgstr ""
+msgstr "подразбирани"
 
 #. ~ "eased" is a noise parameter flag.
 #. It is used to make the map smoother and
@@ -726,15 +727,15 @@ msgstr ""
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "$1 (Enabled)"
-msgstr ""
+msgstr "$1 (включено)"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "$1 mods"
-msgstr ""
+msgstr "$1 модификации"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Failed to install $1 to $2"
-msgstr ""
+msgstr "Грешка при инсталиране на $1 в $2"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Install Mod: Unable to find real mod name for: $1"
@@ -744,14 +745,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -774,241 +767,241 @@ msgstr ""
 
 #: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp
 msgid "Loading..."
-msgstr "Зарежда..."
+msgstr "Зареждане…"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Public server list is disabled"
-msgstr ""
+msgstr "Списъкът с обществени сървъри е изключен"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
 msgstr ""
-"Опитай да включиш публичния списък на сървъри отново и си провай интернет "
-"връзката."
+"Включете списъка на обществени сървъри и проверете връзката с интернет."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Относно"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
-msgstr ""
+msgstr "Активни сътрудници"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active renderer:"
-msgstr ""
+msgstr "Активен визуализатор:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
-msgstr ""
+msgstr "Основни разработчици"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Open User Data Directory"
-msgstr ""
+msgstr "Папка с данни"
 
 #: builtin/mainmenu/tab_about.lua
 msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"Отваря папката, съдържаща предоставените от потребителя\n"
+"светове, игри, модификации и текстури."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
-msgstr ""
+msgstr "Предишни сътрудници"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Core Developers"
-msgstr ""
+msgstr "Предишни основни разработчици"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Browse online content"
-msgstr ""
+msgstr "Преглед на съдържание онлайн"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Content"
-msgstr ""
+msgstr "Съдържание"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Disable Texture Pack"
-msgstr ""
+msgstr "Изкл. на пакет с текстури"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Information:"
-msgstr ""
+msgstr "Описание:"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Installed Packages:"
-msgstr ""
+msgstr "Инсталирани пакети:"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "No dependencies."
-msgstr ""
+msgstr "Няма зависимости."
 
 #: builtin/mainmenu/tab_content.lua
 msgid "No package description available"
-msgstr ""
+msgstr "Пакетът няма описание"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Rename"
-msgstr ""
+msgstr "Преименуване"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Uninstall Package"
-msgstr ""
+msgstr "Премахване на пакет"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Use Texture Pack"
-msgstr ""
+msgstr "Вкл. на пакет с текстури"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Announce Server"
-msgstr ""
+msgstr "Обявяване на сървъра"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Bind Address"
-msgstr ""
+msgstr "Адрес за свързване"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Creative Mode"
-msgstr ""
+msgstr "Творчески режим"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Enable Damage"
-msgstr ""
+msgstr "Получаване на щети"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Game"
-msgstr ""
+msgstr "Създаване на игра"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Server"
-msgstr ""
+msgstr "Създаване на сървър"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Install games from ContentDB"
-msgstr ""
+msgstr "Инсталиране на игри от ContentDB"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "Име"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
-msgstr ""
+msgstr "Създаване"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "No world created or selected!"
-msgstr ""
+msgstr "Не е създаден или избран свят!"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Password"
-msgstr ""
+msgstr "Парола"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
-msgstr ""
+msgstr "Започване на игра"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Port"
-msgstr ""
+msgstr "Порт"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select Mods"
-msgstr ""
+msgstr "Модификации"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select World:"
-msgstr ""
+msgstr "Избор на свят:"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Server Port"
-msgstr ""
+msgstr "Порт на сървъра"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Start Game"
-msgstr ""
+msgstr "Създаване на игра"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Address"
-msgstr ""
+msgstr "Адрес"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
-msgstr ""
+msgstr "Изчистване"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Connect"
-msgstr ""
+msgstr "Свързване"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Creative mode"
-msgstr ""
+msgstr "Творчески режим"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
 msgid "Damage / PvP"
-msgstr ""
+msgstr "Щети / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
-msgstr ""
+msgstr "Премах. любим"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Favorites"
-msgstr ""
+msgstr "Любими"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Несъвместими сървъри"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
-msgstr ""
+msgstr "Включване към игра"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Ping"
-msgstr ""
+msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Ð\92лажни Ñ\80еки"
+msgstr "Ð\9eбÑ\89еÑ\81Ñ\82вени Ñ\81Ñ\8aÑ\80вÑ\8aÑ\80и"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Презареждане"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Server Description"
-msgstr ""
+msgstr "Описание на сървър"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
-msgstr ""
+msgstr "2x"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "3D Clouds"
-msgstr ""
+msgstr "Тримерни облаци"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "4x"
-msgstr ""
+msgstr "4x"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "8x"
-msgstr ""
+msgstr "8x"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "All Settings"
-msgstr ""
+msgstr "Всички настройки"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Antialiasing:"
-msgstr ""
+msgstr "Сгласяне:"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Autosave Screen Size"
-msgstr ""
+msgstr "Авт. запазване на размера"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Bilinear Filter"
@@ -1016,83 +1009,86 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua src/client/game.cpp
 msgid "Change Keys"
-msgstr ""
+msgstr "Промяна на клавиши"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Connected Glass"
-msgstr ""
+msgstr "Свързано стъкло"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "Динамични сенки"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Динамични сенки: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
-msgstr ""
+msgstr "Луксозни листа"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Силни"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Слаби"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Нормални"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Mipmap"
-msgstr ""
+msgstr "Миникарта"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Mipmap + Aniso. Filter"
-msgstr ""
+msgstr "Миникарта + анизо. филтър"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "No Filter"
-msgstr ""
+msgstr "Без филтър"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "No Mipmap"
-msgstr ""
+msgstr "Без миникарта"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Node Highlighting"
-msgstr ""
+msgstr "Осветяване на възел"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Node Outlining"
-msgstr ""
+msgstr "Ограждане на възел"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "None"
-msgstr ""
+msgstr "Без"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Leaves"
-msgstr ""
+msgstr "Непрозрачни листа"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Water"
-msgstr ""
+msgstr "Непрозрачна вода"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Particles"
-msgstr ""
+msgstr "Частици"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Screen:"
-msgstr ""
+msgstr "Екран:"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Settings"
-msgstr ""
+msgstr "Настройки"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Shaders"
@@ -1109,19 +1105,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Simple Leaves"
-msgstr ""
+msgstr "Обикновени листа"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Smooth Lighting"
-msgstr ""
+msgstr "Гладко осветление"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Texturing:"
-msgstr ""
-
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
+msgstr "Текстуриране:"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
@@ -1129,7 +1121,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Touchthreshold: (px)"
-msgstr ""
+msgstr "Праг на докосване: (px)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Trilinear Filter"
@@ -1137,43 +1129,43 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Много силни"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Много слаби"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
-msgstr ""
+msgstr "Поклащащи се листа"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Liquids"
-msgstr ""
+msgstr "Поклащащи се течности"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Plants"
-msgstr ""
+msgstr "Поклащащи се растения"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
-msgstr ""
+msgstr "Времето за свързване изтече."
 
 #: src/client/client.cpp
 msgid "Done!"
-msgstr ""
+msgstr "Готово!"
 
 #: src/client/client.cpp
 msgid "Initializing nodes"
-msgstr ""
+msgstr "Иницииране на възли"
 
 #: src/client/client.cpp
 msgid "Initializing nodes..."
-msgstr ""
+msgstr "Иницииране на възли…"
 
 #: src/client/client.cpp
 msgid "Loading textures..."
-msgstr ""
+msgstr "Зареждане на текстури…"
 
 #: src/client/client.cpp
 msgid "Rebuilding shaders..."
@@ -1181,11 +1173,11 @@ msgstr ""
 
 #: src/client/clientlauncher.cpp
 msgid "Connection error (timed out?)"
-msgstr ""
+msgstr "Грешка при свързване (изтекло време?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr ""
+msgid "Could not find or load game"
+msgstr "Не може да бъде намерена или заредена игра: "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1193,106 +1185,140 @@ msgstr ""
 
 #: src/client/clientlauncher.cpp
 msgid "Main Menu"
-msgstr ""
+msgstr "Главно меню"
 
 #: src/client/clientlauncher.cpp
 msgid "No world selected and no address provided. Nothing to do."
-msgstr ""
+msgstr "Няма избран свят, нито зададен адрес. Няма какво да бъде направено."
 
 #: src/client/clientlauncher.cpp
 msgid "Player name too long."
-msgstr ""
+msgstr "Името на играча е твърде дълго."
 
 #: src/client/clientlauncher.cpp
 msgid "Please choose a name!"
-msgstr ""
+msgstr "Изберете име!"
 
 #: src/client/clientlauncher.cpp
 msgid "Provided password file failed to open: "
-msgstr ""
+msgstr "Файлът с пароли не се отваря: "
 
 #: src/client/clientlauncher.cpp
 msgid "Provided world path doesn't exist: "
-msgstr ""
+msgstr "Зададеният път към света не съществува: "
 
 #: src/client/game.cpp
 msgid ""
 "\n"
 "Check debug.txt for details."
 msgstr ""
+"\n"
+"Прегледайте debug.txt за повече информация."
 
 #: src/client/game.cpp
 msgid "- Address: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
+msgstr "- Адрес: "
 
 #: src/client/game.cpp
 msgid "- Mode: "
-msgstr ""
+msgstr "- Режим: "
 
 #: src/client/game.cpp
 msgid "- Port: "
-msgstr ""
+msgstr "- Порт: "
 
 #: src/client/game.cpp
 msgid "- Public: "
-msgstr ""
+msgstr "- Обществен: "
 
 #. ~ PvP = Player versus Player
 #: src/client/game.cpp
+#, fuzzy
 msgid "- PvP: "
-msgstr ""
+msgstr "- PvP: "
 
 #: src/client/game.cpp
 msgid "- Server Name: "
-msgstr ""
+msgstr "- Име на сървър: "
+
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Възникна грешка:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Достъпът е отказан. Причина: %s"
 
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
-msgstr ""
+msgstr "Автоматичното движение напред е изключено"
 
 #: src/client/game.cpp
 msgid "Automatic forward enabled"
+msgstr "Автоматичното движение напред е включено"
+
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds hidden"
+msgstr "Граници на блокове"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
 msgstr ""
 
 #: src/client/game.cpp
-msgid "Camera update disabled"
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Camera update disabled"
+msgstr "Опресняването на екрана при движение е изключено"
+
 #: src/client/game.cpp
 msgid "Camera update enabled"
+msgstr "Опресняването на екрана при движение е включено"
+
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
 msgstr ""
 
 #: src/client/game.cpp
 msgid "Change Password"
-msgstr ""
+msgstr "Промяна на парола"
 
 #: src/client/game.cpp
 msgid "Cinematic mode disabled"
-msgstr ""
+msgstr "Кинематографичният режим е изключен"
 
 #: src/client/game.cpp
 msgid "Cinematic mode enabled"
-msgstr ""
+msgstr "Кинематографичният режим е включен"
+
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Клиентът е изключен"
 
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
-msgstr ""
+msgstr "Изпълняване на скриптове от страната на клиента е изключено"
 
 #: src/client/game.cpp
 msgid "Connecting to server..."
-msgstr ""
+msgstr "Свързване със сървър…"
+
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Грешка във връзката поради неизвестна причина"
 
 #: src/client/game.cpp
 msgid "Continue"
-msgstr ""
+msgstr "Продължаване"
 
 #: src/client/game.cpp
 #, c-format
@@ -1312,14 +1338,33 @@ msgid ""
 "- Mouse wheel: select item\n"
 "- %s: chat\n"
 msgstr ""
+"Управление:\n"
+"- %s: движение напред\n"
+"- %s: движение назад\n"
+"- %s: движение наляво\n"
+"- %s: движение надясно\n"
+"- %s: скачане/катерене\n"
+"- %s: копаене/удар\n"
+"- %s: поставяне/използване\n"
+"- %s: промъкване/слизане\n"
+"- %s: пускане на предмет\n"
+"- %s: инвентар\n"
+"- мишка: завъртане/разглеждане\n"
+"- колелце на мишка: избор на предмет\n"
+"- %s: разговор\n"
 
 #: src/client/game.cpp
-msgid "Creating client..."
+#, c-format
+msgid "Couldn't resolve address: %s"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Creating client..."
+msgstr "Създаване на клиент…"
+
 #: src/client/game.cpp
 msgid "Creating server..."
-msgstr ""
+msgstr "Създаване на сървър…"
 
 #: src/client/game.cpp
 msgid "Debug info and profiler graph hidden"
@@ -1351,67 +1396,67 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Disabled unlimited viewing range"
-msgstr ""
+msgstr "Неограниченият обхват на видимост е изключен"
 
 #: src/client/game.cpp
 msgid "Enabled unlimited viewing range"
-msgstr ""
+msgstr "Неограниченият обхват на видимост е включен"
 
 #: src/client/game.cpp
 msgid "Exit to Menu"
-msgstr ""
+msgstr "Изход към менюто"
 
 #: src/client/game.cpp
 msgid "Exit to OS"
-msgstr ""
+msgstr "Изход към ОС"
 
 #: src/client/game.cpp
 msgid "Fast mode disabled"
-msgstr ""
+msgstr "Режимът на бързо движение е изключен"
 
 #: src/client/game.cpp
 msgid "Fast mode enabled"
-msgstr ""
+msgstr "Режимът на бързо движение е включен"
 
 #: src/client/game.cpp
 msgid "Fast mode enabled (note: no 'fast' privilege)"
-msgstr ""
+msgstr "Режимът на бързо движение е включен (заб.: липсва правото „fast“)"
 
 #: src/client/game.cpp
 msgid "Fly mode disabled"
-msgstr ""
+msgstr "Режимът на летене е изключен"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled"
-msgstr ""
+msgstr "Режимът на летене е включен"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled (note: no 'fly' privilege)"
-msgstr ""
+msgstr "Режимът на летене е включен (заб.: липсва правото „fly“)"
 
 #: src/client/game.cpp
 msgid "Fog disabled"
-msgstr ""
+msgstr "Мъглата е изключена"
 
 #: src/client/game.cpp
 msgid "Fog enabled"
-msgstr ""
+msgstr "Мъглата е включена"
 
 #: src/client/game.cpp
 msgid "Game info:"
-msgstr ""
+msgstr "Информация за играта:"
 
 #: src/client/game.cpp
 msgid "Game paused"
-msgstr ""
+msgstr "Играта е на пауза"
 
 #: src/client/game.cpp
 msgid "Hosting server"
-msgstr ""
+msgstr "Домакин на играта"
 
 #: src/client/game.cpp
 msgid "Item definitions..."
-msgstr ""
+msgstr "Дефиниции на предмети…"
 
 #: src/client/game.cpp
 msgid "KiB/s"
@@ -1419,7 +1464,7 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Media..."
-msgstr ""
+msgstr "Медия…"
 
 #: src/client/game.cpp
 msgid "MiB/s"
@@ -1427,160 +1472,175 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Minimap currently disabled by game or mod"
-msgstr ""
+msgstr "Картата е спряна или от играта, или от модификация"
 
 #: src/client/game.cpp
 msgid "Multiplayer"
-msgstr ""
+msgstr "Множество играчи"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
-msgstr ""
+msgstr "Режимът „без изрязване“ е изключен"
 
 #: src/client/game.cpp
 msgid "Noclip mode enabled"
-msgstr ""
+msgstr "Режимът „без изрязване“ е включен"
 
 #: src/client/game.cpp
 msgid "Noclip mode enabled (note: no 'noclip' privilege)"
-msgstr ""
+msgstr "Режимът „без изрязване“ е включен (заб.: липсва правото „noclip“)"
 
 #: src/client/game.cpp
 msgid "Node definitions..."
-msgstr ""
+msgstr "Дефиниции на възли…"
 
 #: src/client/game.cpp
 msgid "Off"
-msgstr ""
+msgstr "Изключено"
 
 #: src/client/game.cpp
 msgid "On"
-msgstr ""
+msgstr "Включено"
 
 #: src/client/game.cpp
 msgid "Pitch move mode disabled"
-msgstr ""
+msgstr "Режимът „промяна на височината“ е изключен"
 
 #: src/client/game.cpp
 msgid "Pitch move mode enabled"
-msgstr ""
+msgstr "Режимът „промяна на височината“ е включен"
 
 #: src/client/game.cpp
 msgid "Profiler graph shown"
-msgstr ""
+msgstr "Графиката на профилатора е показана"
 
 #: src/client/game.cpp
 msgid "Remote server"
-msgstr ""
+msgstr "Отдалечен сървър"
 
 #: src/client/game.cpp
 msgid "Resolving address..."
-msgstr ""
+msgstr "Намиране на адрес…"
 
 #: src/client/game.cpp
 msgid "Shutting down..."
-msgstr ""
+msgstr "Изключване…"
 
 #: src/client/game.cpp
 msgid "Singleplayer"
-msgstr ""
+msgstr "Един играч"
 
 #: src/client/game.cpp
 msgid "Sound Volume"
-msgstr ""
+msgstr "Сила на звука"
 
 #: src/client/game.cpp
 msgid "Sound muted"
-msgstr ""
+msgstr "Звукът е заглушен"
 
 #: src/client/game.cpp
 msgid "Sound system is disabled"
-msgstr ""
+msgstr "Системата за звук е изключена"
 
 #: src/client/game.cpp
 msgid "Sound system is not supported on this build"
-msgstr ""
+msgstr "В това издание не се поддържа звукова система"
 
 #: src/client/game.cpp
 msgid "Sound unmuted"
+msgstr "Звукът е пуснат"
+
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Сървърът вероятно използва друго издание на %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
 msgstr ""
 
 #: src/client/game.cpp
 #, c-format
-msgid "Viewing range changed to %d"
+msgid "Unable to listen on %s because IPv6 is disabled"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Viewing range changed to %d"
+msgstr "Обхватът на видимостта е променен на %d"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range is at maximum: %d"
-msgstr ""
+msgstr "Обхватът на видимостта е на своя максимум: %d"
 
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range is at minimum: %d"
-msgstr ""
+msgstr "Обхватът на видимостта е на своя минимум: %d"
 
 #: src/client/game.cpp
 #, c-format
 msgid "Volume changed to %d%%"
-msgstr ""
+msgstr "Силата на звука е променена на %d%%"
 
 #: src/client/game.cpp
 msgid "Wireframe shown"
-msgstr ""
+msgstr "Показани са телените рамки"
 
 #: src/client/game.cpp
 msgid "Zoom currently disabled by game or mod"
-msgstr ""
+msgstr "Мащабирането е спряно или от играта, или от модификация"
 
 #: src/client/game.cpp
 msgid "ok"
-msgstr ""
+msgstr "добре"
 
 #: src/client/gameui.cpp
 msgid "Chat hidden"
-msgstr ""
+msgstr "Разговорите са скрити"
 
 #: src/client/gameui.cpp
 msgid "Chat shown"
-msgstr ""
+msgstr "Разговорите са видими"
 
 #: src/client/gameui.cpp
 msgid "HUD hidden"
-msgstr ""
+msgstr "HUD скрит"
 
 #: src/client/gameui.cpp
 msgid "HUD shown"
-msgstr ""
+msgstr "HUD видим"
 
 #: src/client/gameui.cpp
 msgid "Profiler hidden"
-msgstr ""
+msgstr "Профилаторът е скрит"
 
 #: src/client/gameui.cpp
 #, c-format
 msgid "Profiler shown (page %d of %d)"
-msgstr ""
+msgstr "Профилаторът е видим (страница %d от %d)"
 
 #: src/client/keycode.cpp
 msgid "Apps"
-msgstr ""
+msgstr "Приложения"
 
 #: src/client/keycode.cpp
 msgid "Backspace"
-msgstr ""
+msgstr "Backspace"
 
 #: src/client/keycode.cpp
 msgid "Caps Lock"
-msgstr ""
+msgstr "Caps Lock"
 
 #: src/client/keycode.cpp
 msgid "Control"
-msgstr ""
+msgstr "Control"
 
 #: src/client/keycode.cpp
 msgid "Down"
-msgstr ""
+msgstr "Надолу"
 
 #: src/client/keycode.cpp
 msgid "End"
@@ -1628,27 +1688,27 @@ msgstr ""
 
 #: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
 msgid "Left"
-msgstr ""
+msgstr "Наляво"
 
 #: src/client/keycode.cpp
 msgid "Left Button"
-msgstr ""
+msgstr "Ляв бутон"
 
 #: src/client/keycode.cpp
 msgid "Left Control"
-msgstr ""
+msgstr "Ляв Control"
 
 #: src/client/keycode.cpp
 msgid "Left Menu"
-msgstr ""
+msgstr "Ляв Menu"
 
 #: src/client/keycode.cpp
 msgid "Left Shift"
-msgstr ""
+msgstr "Ляв Shift"
 
 #: src/client/keycode.cpp
 msgid "Left Windows"
-msgstr ""
+msgstr "Ляв Windows"
 
 #. ~ Key name, common on Windows keyboards
 #: src/client/keycode.cpp
@@ -1657,7 +1717,7 @@ msgstr ""
 
 #: src/client/keycode.cpp
 msgid "Middle Button"
-msgstr ""
+msgstr "Среден бутон"
 
 #: src/client/keycode.cpp
 msgid "Num Lock"
@@ -1754,31 +1814,31 @@ msgstr ""
 
 #: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
 msgid "Right"
-msgstr ""
+msgstr "Дясно"
 
 #: src/client/keycode.cpp
 msgid "Right Button"
-msgstr ""
+msgstr "Десен бутон"
 
 #: src/client/keycode.cpp
 msgid "Right Control"
-msgstr ""
+msgstr "Десен Control"
 
 #: src/client/keycode.cpp
 msgid "Right Menu"
-msgstr ""
+msgstr "Десен Menu"
 
 #: src/client/keycode.cpp
 msgid "Right Shift"
-msgstr ""
+msgstr "Десен Shift"
 
 #: src/client/keycode.cpp
 msgid "Right Windows"
-msgstr ""
+msgstr "Десен Windows"
 
 #: src/client/keycode.cpp
 msgid "Scroll Lock"
-msgstr ""
+msgstr "Scroll Lock"
 
 #. ~ Key name
 #: src/client/keycode.cpp
@@ -1787,27 +1847,27 @@ msgstr ""
 
 #: src/client/keycode.cpp
 msgid "Shift"
-msgstr ""
+msgstr "Shift"
 
 #: src/client/keycode.cpp
 msgid "Sleep"
-msgstr ""
+msgstr "Sleep"
 
 #: src/client/keycode.cpp
 msgid "Snapshot"
-msgstr ""
+msgstr "Снимка на екрана"
 
 #: src/client/keycode.cpp
 msgid "Space"
-msgstr ""
+msgstr "Интервал"
 
 #: src/client/keycode.cpp
 msgid "Tab"
-msgstr ""
+msgstr "Табулатор"
 
 #: src/client/keycode.cpp
 msgid "Up"
-msgstr ""
+msgstr "Нагоре"
 
 #: src/client/keycode.cpp
 msgid "X Button 1"
@@ -1819,33 +1879,41 @@ msgstr ""
 
 #: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
 msgid "Zoom"
-msgstr ""
+msgstr "Мащабиране"
 
 #: src/client/minimap.cpp
 msgid "Minimap hidden"
-msgstr ""
+msgstr "Картата е скрита"
 
 #: src/client/minimap.cpp
 #, c-format
 msgid "Minimap in radar mode, Zoom x%d"
-msgstr ""
+msgstr "Картата е в режим на радар, мащаб x%d"
 
 #: src/client/minimap.cpp
 #, c-format
 msgid "Minimap in surface mode, Zoom x%d"
-msgstr ""
+msgstr "Картата е в режим на повърхност, мащаб x%d"
 
 #: src/client/minimap.cpp
 msgid "Minimap in texture mode"
-msgstr ""
+msgstr "Картата е в режим на текстура"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Грешка при отваряне на страница"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Отваряне на страница"
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
-msgstr ""
+msgstr "Паролите не съвпадат!"
 
 #: src/gui/guiConfirmRegistration.cpp
 msgid "Register and Join"
-msgstr ""
+msgstr "Регистриране и вход"
 
 #: src/gui/guiConfirmRegistration.cpp
 #, c-format
@@ -1856,192 +1924,199 @@ msgid ""
 "Please retype your password and click 'Register and Join' to confirm account "
 "creation, or click 'Cancel' to abort."
 msgstr ""
+"На път сте да влезете в сървъра с име „%s“ за първи път.\n"
+"Ако продължите нова сметка с тези данни ще бъде създадена на сървъра.\n"
+"Въведете паролата отново и натиснете „Регистриране и вход“, за да потвърдите "
+"или „Отказ“ за връщане обратно."
 
 #: src/gui/guiFormSpecMenu.cpp
 msgid "Proceed"
-msgstr ""
+msgstr "Напред"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "\"Aux1\" = climb down"
-msgstr ""
+msgstr "„Aux1“ = слизане"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
-msgstr ""
+msgstr "Автоматично напред"
 
 #: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
 msgid "Automatic jumping"
-msgstr ""
+msgstr "Автоматично скачане"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
-msgstr ""
+msgstr "Назад"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Граници на блокове"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
-msgstr ""
+msgstr "Промяна на камера"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Chat"
-msgstr ""
+msgstr "Разговори"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Command"
-msgstr ""
+msgstr "Команда"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Console"
-msgstr ""
+msgstr "Конзола"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. range"
-msgstr ""
+msgstr "Намал. на обхвата"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. volume"
-msgstr ""
+msgstr "Намал. на звука"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Double tap \"jump\" to toggle fly"
-msgstr ""
+msgstr "Двоен „скок“ превключва летене"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Drop"
-msgstr ""
+msgstr "Пускане предмет"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Forward"
-msgstr ""
+msgstr "Напред"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. range"
-msgstr ""
+msgstr "Увелич. на обхвата"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. volume"
-msgstr ""
+msgstr "Увелич. на звука"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inventory"
-msgstr ""
+msgstr "Инвентар"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Jump"
-msgstr ""
+msgstr "Скок"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Key already in use"
-msgstr ""
+msgstr "Клавишът вече се ползва"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
 msgstr ""
+"Клавишни комбинации (Ако екранът изглежда счупен махнете нещата от minetest."
+"conf)"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Local command"
-msgstr ""
+msgstr "Местна команда"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Mute"
-msgstr ""
+msgstr "Заглушаване"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Next item"
-msgstr ""
+msgstr "След. предмет"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Prev. item"
-msgstr ""
+msgstr "Пред. предмет"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Range select"
-msgstr ""
+msgstr "Обхват видимост"
 
 #: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
 msgid "Screenshot"
-msgstr ""
+msgstr "Снимка на екрана"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Sneak"
-msgstr ""
+msgstr "Промъкване"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle HUD"
-msgstr ""
+msgstr "Превкл. HUD"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle chat log"
-msgstr ""
+msgstr "Превкл. разговори"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle fast"
-msgstr ""
+msgstr "Превкл. бързина"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle fly"
-msgstr ""
+msgstr "Превкл. полет"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle fog"
-msgstr ""
+msgstr "Превкл. мъгла"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle minimap"
-msgstr ""
+msgstr "Превкл. карта"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle noclip"
-msgstr ""
+msgstr "Превкл. изрязване"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle pitchmove"
-msgstr ""
+msgstr "Превкл. „pitchmove“"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "press key"
-msgstr ""
+msgstr "избор бутон"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Change"
-msgstr ""
+msgstr "Променяне"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Confirm Password"
-msgstr ""
+msgstr "Потвърж. на парола"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "New Password"
-msgstr ""
+msgstr "Нова парола"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Old Password"
-msgstr ""
+msgstr "Стара парола"
 
 #: src/gui/guiVolumeChange.cpp
 msgid "Exit"
-msgstr ""
+msgstr "Изход"
 
 #: src/gui/guiVolumeChange.cpp
 msgid "Muted"
-msgstr ""
+msgstr "Без звук"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr ""
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Сила на звука: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
 #: src/gui/modalMenu.cpp
 msgid "Enter "
-msgstr ""
+msgstr "Въведете "
 
 #. ~ DO NOT TRANSLATE THIS LITERALLY!
 #. This is a special string which needs to contain the translation's
@@ -2241,6 +2316,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2339,15 +2418,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Automatically jump up single-node obstacles."
-msgstr ""
+msgstr "Автоматично прескача препятствия от единични възли."
 
 #: src/settings_translation_file.cpp
 msgid "Automatically report to the serverlist."
-msgstr ""
+msgstr "Автоматично докладване в списъка на сървърите."
 
 #: src/settings_translation_file.cpp
 msgid "Autosave screen size"
-msgstr ""
+msgstr "Автоматично запазване на размера на екрана"
 
 #: src/settings_translation_file.cpp
 msgid "Autoscaling mode"
@@ -2395,7 +2474,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Bind address"
-msgstr ""
+msgstr "Адрес за свързване"
 
 #: src/settings_translation_file.cpp
 msgid "Biome API temperature and humidity noise parameters"
@@ -2507,6 +2586,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Команда"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2540,8 +2624,9 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Разговорите са видими"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2559,6 +2644,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2634,6 +2725,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2644,19 +2751,19 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Connects glass if supported by node."
-msgstr ""
+msgstr "Свързва стъкло, ако се поддържа от възела."
 
 #: src/settings_translation_file.cpp
 msgid "Console alpha"
-msgstr ""
+msgstr "Прозрачност на конзолата"
 
 #: src/settings_translation_file.cpp
 msgid "Console color"
-msgstr ""
+msgstr "Цвят на конзолата"
 
 #: src/settings_translation_file.cpp
 msgid "Console height"
-msgstr ""
+msgstr "Височина на конзолата"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Flag Blacklist"
@@ -2690,10 +2797,14 @@ msgid ""
 "Examples:\n"
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
+"Управлява дължината на цикъла ден/нощ.\n"
+"Пример:\n"
+"72 = 20 мин, 360 = 4 мин, 1 = 24 часа, 0 = ден/нощ/каквото е остава без "
+"промяна."
 
 #: src/settings_translation_file.cpp
 msgid "Controls sinking speed in liquid."
-msgstr ""
+msgstr "Управлява скоростта на потъване в течности."
 
 #: src/settings_translation_file.cpp
 msgid "Controls steepness/depth of lake depressions."
@@ -2725,7 +2836,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2794,7 +2905,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Default report format"
-msgstr ""
+msgstr "Формат на отчета по подразбиране"
 
 #: src/settings_translation_file.cpp
 msgid "Default stack size"
@@ -2802,8 +2913,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2921,6 +3032,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2967,7 +3082,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2995,13 +3117,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3086,6 +3201,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3270,11 +3391,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3283,6 +3408,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3342,10 +3478,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3394,7 +3526,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3826,7 +3958,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3910,7 +4042,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4508,7 +4640,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Large cave proportion flooded"
-msgstr ""
+msgstr "Голяма част от пещерите са наводнени"
 
 #: src/settings_translation_file.cpp
 msgid "Large chat console key"
@@ -4739,7 +4871,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5032,7 +5164,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5043,6 +5175,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5164,7 +5300,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5188,11 +5324,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5215,17 +5353,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5269,7 +5403,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Player name"
-msgstr ""
+msgstr "Име на играча"
 
 #: src/settings_translation_file.cpp
 msgid "Player transfer distance"
@@ -5328,14 +5462,14 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Proportion of large caves that contain liquid."
-msgstr ""
+msgstr "Частта от големи пещери, които съдържат течност."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5370,7 +5504,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Remote port"
-msgstr ""
+msgstr "Отдалечен порт"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5581,7 +5715,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Server address"
-msgstr ""
+msgstr "Адрес на сървър"
 
 #: src/settings_translation_file.cpp
 msgid "Server description"
@@ -5593,7 +5727,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Server port"
-msgstr ""
+msgstr "Порт на сървъра"
 
 #: src/settings_translation_file.cpp
 msgid "Server side occlusion culling"
@@ -5623,26 +5757,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5733,7 +5859,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5838,6 +5964,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5948,7 +6082,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5966,7 +6100,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6035,7 +6169,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6128,6 +6262,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6198,7 +6336,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6381,6 +6519,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6402,7 +6544,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6410,14 +6552,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6543,24 +6678,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6573,8 +6690,20 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Творчески режим: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Щети: "
+
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Инсталиране: файл: „$1“"
+
 #~ msgid "View"
 #~ msgstr "Гледане"
 
+#~ msgid "You died."
+#~ msgstr "Умряхте."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index a388ebfc1a2ed86441be17800e3b6a901b7dc3c8..b2399974420e4e01d3780a5a1833553d744d9866 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Catalan (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: Catalan <https://hosted.weblate.org/projects/minetest/"
@@ -64,11 +64,6 @@ msgstr "Reaparèixer"
 msgid "You died"
 msgstr "Has mort."
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Has mort."
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -100,6 +95,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 #, fuzzy
 msgid "An error occurred in a Lua script:"
@@ -319,6 +318,13 @@ msgstr "Instal·lar"
 msgid "Install missing dependencies"
 msgstr "Dependències opcionals:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"\n"
+"Instal·lar mod: Format de arxiu \"$1\" no suportat o arxiu corrupte"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -664,7 +670,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -783,18 +789,6 @@ msgstr ""
 "Instal·lar mod: Impossible de trobar el nom de la carpeta adequat per al "
 "paquet de mods $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"\n"
-"Instal·lar mod: Format de arxiu \"$1\" no suportat o arxiu corrupte"
-
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: file: \"$1\""
-msgstr "Instal·lar mod: Arxiu: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 #, fuzzy
 msgid "Unable to find a valid mod or modpack"
@@ -1189,10 +1183,6 @@ msgstr "Il·luminació suau"
 msgid "Texturing:"
 msgstr "Texturització:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Per habilitar les ombres el controlador OpenGL ha ser utilitzat."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1227,7 +1217,7 @@ msgstr "Moviment de les Fulles"
 msgid "Waving Plants"
 msgstr "Moviment de Plantes"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Temps d'espera de la connexió esgotat."
 
@@ -1256,7 +1246,8 @@ msgid "Connection error (timed out?)"
 msgstr "Error de connexió (¿temps esgotat?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "No es pot trobar o carregar el joc \""
 
 #: src/client/clientlauncher.cpp
@@ -1300,16 +1291,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "Adreça BIND"
 
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Creative Mode: "
-msgstr "Mode Creatiu"
-
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Damage: "
-msgstr "Dany"
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1333,6 +1314,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Ha ocorregut un error:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Automatic forward disabled"
@@ -1343,6 +1334,22 @@ msgstr "Tecla Avançar"
 msgid "Automatic forward enabled"
 msgstr "Tecla Avançar"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Camera update disabled"
@@ -1353,6 +1360,10 @@ msgstr "Tecla alternativa per a l'actualització de la càmera"
 msgid "Camera update enabled"
 msgstr "Tecla alternativa per a l'actualització de la càmera"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Canviar contrasenya"
@@ -1367,6 +1378,11 @@ msgstr "Tecla mode cinematogràfic"
 msgid "Cinematic mode enabled"
 msgstr "Tecla mode cinematogràfic"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Client"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1375,6 +1391,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr "Connectant al servidor ..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Continuar"
@@ -1409,6 +1429,11 @@ msgstr ""
 "- Roda ratolí: triar objecte\n"
 "- T: xat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Creant client ..."
@@ -1625,6 +1650,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Volum del so"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1968,6 +2008,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Error al instal·lar $1 en $2"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Les contrasenyes no coincideixen!"
@@ -2177,7 +2226,8 @@ msgid "Muted"
 msgstr "Utilitza la tecla"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Volum de so: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2413,6 +2463,10 @@ msgstr ""
 "Ajustar la configuració de punts per polsada (dpi) a la teva pantalla (no "
 "X11/Sols Android) Ex. per a pantalles amb 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2693,6 +2747,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Comands de xat"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2729,8 +2788,8 @@ msgid "Chat toggle key"
 msgstr "Tecla alternativa per al xat"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Comands de xat"
+msgid "Chat weblinks"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2748,6 +2807,12 @@ msgstr "Tecla mode cinematogràfic"
 msgid "Clean transparent textures"
 msgstr "Netejar textures transparents"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Client"
@@ -2833,6 +2898,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Tecla comandament"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Connectar vidre"
@@ -2932,7 +3013,7 @@ msgstr "Punt de mira Alpha"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3013,8 +3094,8 @@ msgstr "Joc per defecte"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3135,6 +3216,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3182,7 +3267,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3210,13 +3302,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Habilitar l'entrada aleatòria d'usuari (només utilitzat per testing)."
@@ -3301,6 +3386,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3489,11 +3580,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3502,6 +3597,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3561,10 +3667,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3613,7 +3715,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4054,7 +4156,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4139,7 +4241,7 @@ msgid "Joystick button repetition interval"
 msgstr "Interval de repetició del click dret"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5189,7 +5291,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5491,7 +5593,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5502,6 +5604,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5624,7 +5730,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5648,11 +5754,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5675,17 +5783,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5792,9 +5896,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6111,26 +6215,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6222,7 +6318,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6332,6 +6428,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6443,7 +6547,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6461,7 +6565,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6530,7 +6634,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6630,6 +6734,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr "Llindar tàctil (px)"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6701,7 +6809,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6889,6 +6997,10 @@ msgstr "Onatge"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6910,7 +7022,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6918,14 +7030,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7055,24 +7160,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -7085,6 +7172,14 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#, fuzzy
+#~ msgid "- Creative Mode: "
+#~ msgstr "Mode Creatiu"
+
+#, fuzzy
+#~ msgid "- Damage: "
+#~ msgstr "Dany"
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7158,6 +7253,10 @@ msgstr ""
 #~ msgid "Generate Normal Maps"
 #~ msgstr "Generar Mapes Normals"
 
+#, fuzzy
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instal·lar mod: Arxiu: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "Principal"
 
@@ -7202,11 +7301,18 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Començar Un Jugador"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Per habilitar les ombres el controlador OpenGL ha ser utilitzat."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Activar Cinematogràfic"
 
 #~ msgid "Yes"
 #~ msgstr "Sí"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Has mort."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index ac3d06de3a45e57b713cb9e967402cd5da18cb50..811c39f060acd16fbe7bb4f6300885a91c5334ec 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Czech (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-02-03 04:31+0000\n"
-"Last-Translator: Vít Skalický <vit.skalicky@email.cz>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-11-22 18:50+0000\n"
+"Last-Translator: Ondřej Pfrogner <ondrej.andre.pfrogner@gmail.com>\n"
 "Language-Team: Czech <https://hosted.weblate.org/projects/minetest/minetest/"
 "cs/>\n"
 "Language: cs\n"
@@ -12,48 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.5-dev\n"
+"X-Generator: Weblate 4.10-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Vyprázdnit frontu odchozího chatu"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Příkazy"
+msgstr "Prázdný příkaz."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Odejít do nabídky"
+msgstr "Odejít do hlavní nabídky"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Místní příkaz"
+msgstr "Neplatný příkaz: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Zadaný příkaz: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Místní hra"
+msgstr "Vypsat připojené hráče"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Místní hra"
+msgstr "Připojení hráči: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Fronta odchozího chatu je nyní prázdná."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Server zakázal tento příkaz."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -63,41 +58,41 @@ msgstr "Oživit"
 msgid "You died"
 msgstr "Zemřel jsi"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Zemřel jsi"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Místní příkaz"
+msgstr "Příkazy k dispozici:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Místní příkaz"
+msgstr "Příkazy k dispozici: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Příkaz není k dispozici: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Získat nápovědu pro příkazy"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Použij \".help <příkaz>\" pro obdržení více informací, nebo \".help all\" "
+"pro celý výpis."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <příkaz>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
-msgstr "OK"
+msgstr "Dobře"
+
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Příkaz není k dispozici: "
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
@@ -117,7 +112,7 @@ msgstr "Znovu se připojit"
 
 #: builtin/fstk/ui.lua
 msgid "The server has requested a reconnect:"
-msgstr "Server vyžaduje znovupřipojení se:"
+msgstr "Server vyžaduje opětovné připojení:"
 
 #: builtin/mainmenu/common.lua
 msgid "Protocol version mismatch. "
@@ -230,7 +225,7 @@ msgstr "\"$1\" již existuje. Chcete jej přepsat?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
-msgstr ""
+msgstr "Budou nainstalovány závislosti $1 a $2."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
@@ -250,38 +245,36 @@ msgstr "$1 se stahuje..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr ""
+msgstr "$1 požadovaných závislostí nebylo nalezeno."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
-msgstr ""
+msgstr "$1 závislostí bude nainstalováno a $2 bude vynecháno."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "All packages"
 msgstr "Všechny balíčky"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Already installed"
-msgstr "Klávesa je již používána"
+msgstr "Již nainstalováno"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Back to Main Menu"
 msgstr "Zpět do hlavní nabídky"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Base Game:"
-msgstr "Založit hru"
+msgstr "Základní hra:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
 msgstr ""
+"ContentDB není přístupná pokud byl Minetest kompilován bez použití cURL"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Downloading..."
-msgstr "Nahrávám..."
+msgstr "Stahuji..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Failed to download $1"
@@ -297,14 +290,18 @@ msgid "Install"
 msgstr "Instalovat"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install $1"
-msgstr "Instalovat"
+msgstr "Instalovat $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install missing dependencies"
-msgstr "Volitelné závislosti:"
+msgstr "Instalovat chybějící závislosti"
+
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"Instalace rozšíření: poškozený archiv nebo nepodporovaný typ souboru \"$1\""
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -320,25 +317,24 @@ msgid "No results"
 msgstr "Žádné výsledky"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "No updates"
-msgstr "Aktualizovat"
+msgstr "Žádné aktualizace"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Not found"
-msgstr ""
+msgstr "Nenalezeno"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
-msgstr ""
+msgstr "Přepsat"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Please check that the base game is correct."
-msgstr ""
+msgstr "Ověř prosím, zda je základní hra v pořádku."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "Ve frontě"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Texture packs"
@@ -354,57 +350,51 @@ msgstr "Aktualizovat"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
-msgstr ""
+msgstr "Aktualizovat vše [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "Zobrazit více informací v prohlížeči"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
-msgstr "Svět s názvem \"$1\" už existuje"
+msgstr "Svět s názvem \"$1\" již existuje"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Additional terrain"
-msgstr ""
+msgstr "Další terén"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Altitude chill"
-msgstr "Výškové ochlazení"
+msgstr "Teplota (výšková)"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Altitude dry"
-msgstr "Výškové ochlazení"
+msgstr "Vlhkost (výšková)"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biome blending"
-msgstr "Šum biomů"
+msgstr "Prolínání biomů"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biomes"
-msgstr "Šum biomů"
+msgstr "Biomy"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caverns"
-msgstr "Šum jeskynních dutin"
+msgstr "Jeskyně (velké)"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caves"
-msgstr "Oktávy"
+msgstr "Jeskyně (malé)"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Create"
 msgstr "Vytvořit"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Decorations"
-msgstr "Iterace"
+msgstr "Dekorace"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download a game, such as Minetest Game, from minetest.net"
@@ -415,23 +405,20 @@ msgid "Download one from minetest.net"
 msgstr "Stáhněte si jednu z minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Dungeons"
-msgstr "Å um hÅ\99betů"
+msgstr "ŽaláÅ\99e"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Flat terrain"
-msgstr ""
+msgstr "Plochý terén"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Floating landmasses in the sky"
-msgstr "Koncentrace hor na létajících ostrovech"
+msgstr "Krajina vznášející se na nebi"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Floatlands (experimental)"
-msgstr "Výška létajících ostrovů"
+msgstr "Létající ostrovy (experimentální)"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Game"
@@ -439,28 +426,27 @@ msgstr "Hra"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Generate non-fractal terrain: Oceans and underground"
-msgstr ""
+msgstr "Generovat terén bez použití fraktálů: Oceány a podzemí"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Hills"
-msgstr ""
+msgstr "Kopce"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Humid rivers"
-msgstr "Ovladač grafiky"
+msgstr "Vodnost řek"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Increases humidity around rivers"
-msgstr ""
+msgstr "Zvyšuje vlhkost v okolí řek"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Lakes"
-msgstr ""
+msgstr "Jezera"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Low humidity and high heat causes shallow or dry rivers"
-msgstr ""
+msgstr "Nízká vlhkost a vysoké teploty mají za následek mělké či vyschlé řeky"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen"
@@ -468,24 +454,23 @@ msgstr "Generátor mapy"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen flags"
-msgstr "Nastavení generátoru mapy"
+msgstr "Nastavení pro Generátor mapy"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Mapgen-specific flags"
-msgstr "Mapgen údolí"
+msgstr "Nastavení pro Generátor mapy"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mountains"
-msgstr ""
+msgstr "Hory"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mud flow"
-msgstr ""
+msgstr "Eroze"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Network of tunnels and caves"
-msgstr ""
+msgstr "Jeskynní systém"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "No game selected"
@@ -493,20 +478,19 @@ msgstr "Není vybrána žádná hra"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces heat with altitude"
-msgstr ""
+msgstr "Snižuje teplotu a nadmořskou výšku"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces humidity with altitude"
-msgstr ""
+msgstr "Snižuje vlhkost s rostoucí nadmořskou výškou"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Rivers"
-msgstr "Velikost řeky"
+msgstr "Řeky"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Sea level rivers"
-msgstr ""
+msgstr "Řeky v úrovni mořské hladiny"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -515,51 +499,51 @@ msgstr "Seedové číslo"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Smooth transition between biomes"
-msgstr ""
+msgstr "Pozvolný přechod mezi biomy"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid ""
 "Structures appearing on the terrain (no effect on trees and jungle grass "
 "created by v6)"
 msgstr ""
+"Povrchové struktury (nemá vliv na stromy a tropickou trávu vytvořené ve v6 a "
+"později)"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Structures appearing on the terrain, typically trees and plants"
-msgstr ""
+msgstr "Povrchové struktury, především stromy a rostliny"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert"
-msgstr ""
+msgstr "Mírné, Poušť"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle"
-msgstr ""
+msgstr "Mírné, Poušť, Džungle"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr ""
+msgstr "Mírné, Poušť, Džungle, Tundra, Tajga"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Terrain surface erosion"
-msgstr ""
+msgstr "Povrchová eroze"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
-msgstr ""
+msgstr "Stromy a tropická tráva"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Vary river depth"
-msgstr "Hloubka řeky"
+msgstr "Proměnná hloubka řek"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Very large caverns deep in the underground"
-msgstr ""
+msgstr "Veliké jeskyně hluboko pod zemí"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Warning: The Development Test is meant for developers."
-msgstr "Varování: \"Minimal development test\" je zamýšlen pouze pro vývojáře."
+msgstr "Varování: Development Test je určen pro vývojáře."
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "World name"
@@ -648,7 +632,8 @@ msgid "Offset"
 msgstr "Odstup"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Urputnost"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -760,15 +745,6 @@ msgstr ""
 "Instalace rozšíření: nenalezen vhodný adresář s příslušným názvem pro "
 "balíček $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Instalace rozšíření: poškozený archiv nebo nepodporovaný typ souboru \"$1\""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instalace: soubor: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Platné rozšíření nebylo nalezeno"
@@ -794,9 +770,8 @@ msgid "Loading..."
 msgstr "Nahrávám..."
 
 #: builtin/mainmenu/serverlistmgr.lua
-#, fuzzy
 msgid "Public server list is disabled"
-msgstr "Uživatelské skripty nejsou povoleny"
+msgstr "Seznam veřejných serverů je vypnut"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
@@ -806,31 +781,31 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "O nás"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Aktivní přispěvatelé"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Odesílací rozsah aktivních bloků"
+msgstr "Aktivní renderer:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
 msgstr "Hlavní vývojáři"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Open User Data Directory"
-msgstr "Vyberte adresář"
+msgstr "Otevřít uživatelský adresář"
 
 #: builtin/mainmenu/tab_about.lua
 msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"Ve správci souborů otevře adresář obsahující uživatelské světy, hry,\n"
+"mody a balíčky textur."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
@@ -906,11 +881,11 @@ msgstr "Založit server"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Install games from ContentDB"
-msgstr ""
+msgstr "Instalovat hry z ContentDB"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "Jméno"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
@@ -921,9 +896,8 @@ msgid "No world created or selected!"
 msgstr "Žádný svět nebyl vytvořen ani vybrán!"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Password"
-msgstr "Nové heslo"
+msgstr "Heslo"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
@@ -934,9 +908,8 @@ msgid "Port"
 msgstr "Port"
 
 #: builtin/mainmenu/tab_local.lua
-#, fuzzy
 msgid "Select Mods"
-msgstr "Vyberte svět:"
+msgstr "Vybrat mody"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select World:"
@@ -951,9 +924,8 @@ msgid "Start Game"
 msgstr "Spustit hru"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adresa: "
+msgstr "Adresa"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -969,22 +941,20 @@ msgstr "Kreativní mód"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Zranění"
+msgstr "Zranění / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Smazat oblíbené"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "Oblíbené"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Nekompatibilní server"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -995,16 +965,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Uveřejnit server"
+msgstr "Veřejné servery"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Obnovit"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Popis serveru"
 
@@ -1049,13 +1017,12 @@ msgid "Connected Glass"
 msgstr "Propojené sklo"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Stín písma"
+msgstr "Dynamické stíny"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dynamické stíny: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1063,19 +1030,19 @@ msgstr "Vícevrstevné listí"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Vysoké"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Nízké"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Střední"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
-msgstr "Mipmapy zapnuté"
+msgstr "Mipmapy"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap + Aniso. Filter"
@@ -1126,9 +1093,8 @@ msgid "Shaders"
 msgstr "Shadery"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "Shaders (experimental)"
-msgstr "Výška létajících ostrovů"
+msgstr "Shader (experimentální)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
@@ -1146,10 +1112,6 @@ msgstr "Plynulé osvětlení"
 msgid "Texturing:"
 msgstr "Texturování:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Pro zapnutí shaderů musíte používat OpenGL ovladač."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tone mapping"
@@ -1164,11 +1126,11 @@ msgstr "Trilineární filtr"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Velmi vysoké"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Vylmi nízké"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1182,7 +1144,7 @@ msgstr "Vlnění Kapalin"
 msgid "Waving Plants"
 msgstr "Vlnění rostlin"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Vypršel časový limit připojení."
 
@@ -1211,7 +1173,8 @@ msgid "Connection error (timed out?)"
 msgstr "Chyba spojení (vypršel čas?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Hru nebylo možné nahrát nebo najít \""
 
 #: src/client/clientlauncher.cpp
@@ -1255,14 +1218,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresa: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kreativní mód: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Zranění: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Mód: "
@@ -1284,6 +1239,16 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Název serveru: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Nastala chyba:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automatický posun vpřed zakázán"
@@ -1292,6 +1257,23 @@ msgstr "Automatický posun vpřed zakázán"
 msgid "Automatic forward enabled"
 msgstr "Automatický posun vpřed povolen"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds hidden"
+msgstr "Ohraničení bloku"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Aktualizace kamery (pohledu) zakázána"
@@ -1300,6 +1282,10 @@ msgstr "Aktualizace kamery (pohledu) zakázána"
 msgid "Camera update enabled"
 msgstr "Aktualizace kamery (pohledu) povolena"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Změnit heslo"
@@ -1312,6 +1298,11 @@ msgstr "Filmový režim zakázán"
 msgid "Cinematic mode enabled"
 msgstr "Filmový režim povolen"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Lokální mody"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Uživatelské skripty nejsou povoleny"
@@ -1320,12 +1311,16 @@ msgstr "Uživatelské skripty nejsou povoleny"
 msgid "Connecting to server..."
 msgstr "Připojuji se k serveru..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Pokračovat"
 
 #: src/client/game.cpp
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "Controls:\n"
 "- %s: move forwards\n"
@@ -1348,15 +1343,20 @@ msgstr ""
 "- %s: pohyb doleva\n"
 "- %s: pohyb doprava\n"
 "- %s: skok/výstup\n"
+"- %s: těžit/uhodit\n"
+"- %s: umístit/použít\n"
 "- %s: plížení/sestup\n"
-"- %s: zahození věci\n"
+"- %s: zahození předmětu\n"
 "- %s: inventář\n"
 "- Myš: otáčení/rozhlížení\n"
-"- Levé tl. myši: těžit/uhodit\n"
-"- Pravé tl. myši: položit/použít\n"
-"- Kolečko myši: výběr přihrádky\n"
+"- Kolečko myši: výběr předmětu\n"
 "- %s: chat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Vytvářím klienta..."
@@ -1486,9 +1486,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Minimapa je aktuálně zakázána"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Místní hra"
+msgstr "Multiplayer"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1540,7 +1539,7 @@ msgstr "Vypínání..."
 
 #: src/client/game.cpp
 msgid "Singleplayer"
-msgstr "Místní hra"
+msgstr "Singleplayer"
 
 #: src/client/game.cpp
 msgid "Sound Volume"
@@ -1552,16 +1551,31 @@ msgstr "Zvuk vypnut"
 
 #: src/client/game.cpp
 msgid "Sound system is disabled"
-msgstr ""
+msgstr "Zvukový systém je vypnutý"
 
 #: src/client/game.cpp
 msgid "Sound system is not supported on this build"
-msgstr ""
+msgstr "Zvukový systém není v této verzi podporovaný"
 
 #: src/client/game.cpp
 msgid "Sound unmuted"
 msgstr "Zvuk zapnut"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1883,19 +1897,27 @@ msgid "Minimap hidden"
 msgstr "Minimapa je skryta"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in radar mode, Zoom x%d"
-msgstr "Minimapa v režimu radar, Přiblížení x1"
+msgstr "Minimapa v režimu Radar, Přiblížení x%d"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in surface mode, Zoom x%d"
-msgstr "Minimapa v režimu povrch, Přiblížení x1"
+msgstr "Minimapa v režimu Povrch, Přiblížení x%d"
 
 #: src/client/minimap.cpp
-#, fuzzy
 msgid "Minimap in texture mode"
-msgstr "Minimální velikost textury k filtrování"
+msgstr "Minimapa v režimu Textura"
+
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Selhalo stažení $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
@@ -1925,9 +1947,8 @@ msgid "Proceed"
 msgstr "Pokračovat"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "„Speciální“ = sestoupit dolů"
+msgstr "\"Aux1\" = sestoupit"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1939,7 +1960,7 @@ msgstr "Automaticky skákat"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1947,7 +1968,7 @@ msgstr "Vzad"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Ohraničení bloku"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2100,7 +2121,8 @@ msgid "Muted"
 msgstr "Ztlumeno"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Hlasitost: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2125,14 +2147,13 @@ msgstr ""
 "Pokud je zakázán, virtuální joystick se upraví podle umístění prvního dotyku."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Použít virtuální joystick pro stisknutí tlačítka 'aux'.\n"
-"Pokud je povoleno, virtuální joystick automaticky stiskne tlačítko 'aux' "
+"(Android) Použít virtuální joystick pro stisk tlačítka \"Aux1\".\n"
+"Pokud je povoleno, virtuální joystick automaticky stiskne tlačítko \"Aux1\" "
 "pokud je mimo hlavní kruh."
 
 #: src/settings_translation_file.cpp
@@ -2210,9 +2231,8 @@ msgid "3D mode"
 msgstr "Režim 3D zobrazení"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "3D mode parallax strength"
-msgstr "Síla parallax occlusion"
+msgstr "Intezita Parallax ve 3D modu"
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining giant caverns."
@@ -2233,6 +2253,11 @@ msgid ""
 "to be adjusted, as floatland tapering functions best when this noise has\n"
 "a value range of approximately -2.0 to 2.0."
 msgstr ""
+"3D šum definující strukturu létajících ostrovů.\n"
+"Pokud je odlišný od výchozího, může být nutné upravit\n"
+"\"měřítko\" šumu (výchozí 0.7), jelikož zužování (obrácené hory)\n"
+"létajících ostrovů funguje nejlépe pokud je šum v rozmezí přibližně -2.0 až "
+"2.0."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining structure of river canyon walls."
@@ -2248,7 +2273,7 @@ msgstr "3D šum definující horské převisy, atp. Typicky malé odchylky."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise that determines number of dungeons per mapchunk."
-msgstr "3D šum, který definuje počet žalářů na kusu mapy."
+msgstr "3D šum definující počet žalářů na kusu mapy."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2297,12 +2322,11 @@ msgstr "Interval Aktivní Blokové Modifikace (ABM)"
 
 #: src/settings_translation_file.cpp
 msgid "ABM time budget"
-msgstr ""
+msgstr "ABM použitelný čas"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Absolute limit of queued blocks to emerge"
-msgstr "Maximální počet emerge front"
+msgstr "Maximální počet připravených bloků ve frontě"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration in air"
@@ -2350,6 +2374,10 @@ msgstr ""
 "Upraví nastavení DPI pro vaši obrazovku (není pro X11/Android). Pro použití "
 "například s 4k obrazovkami."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2359,6 +2387,11 @@ msgid ""
 "Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n"
 "to be sure) creates a solid floatland layer."
 msgstr ""
+"Upravit hustotu roviny létajících ostrovů.\n"
+"Zvýšením hodnoty se zvýší hustota. Hodnota může být kladná i záporná.\n"
+"Hodnota = 0.0: 50% světa tvoří létajících ostrovy.\n"
+"Hodnota = 2.0 (může být i vyšší v závislosti na “mgv7_np_floatland“,\n"
+"nutno vždy otestovat) vytvoří souvislou vrstvu létajících ostrovů."
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
@@ -2372,6 +2405,11 @@ msgid ""
 "This only has significant effect on daylight and artificial\n"
 "light, it has very little effect on natural night light."
 msgstr ""
+"Změní křivku světla použitím \"gamma korekce\".\n"
+"Vysoké hodnoty zesvětlí málo a středně osvětlené prostory.\n"
+"Hodnota \"1.0\" nastaví výchozí křivku.\n"
+"Tato úprava slouží především pro úpravu denního\n"
+"a umělého osvětlení a má pouze malý dopad na noční osvětlení."
 
 #: src/settings_translation_file.cpp
 msgid "Always fly and fast"
@@ -2398,9 +2436,8 @@ msgid "Announce server"
 msgstr "Zveřejnit server"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Announce to this serverlist."
-msgstr "Zveřejnit server"
+msgstr "Oznámit tomuto seznamu serverů."
 
 #: src/settings_translation_file.cpp
 msgid "Append item name"
@@ -2431,7 +2468,6 @@ msgid "Ask to reconnect after crash"
 msgstr "Zeptat se na znovupřipojení po havárii"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "At this distance the server will aggressively optimize which blocks are sent "
 "to\n"
@@ -2445,29 +2481,26 @@ msgid ""
 "optimization.\n"
 "Stated in mapblocks (16 nodes)."
 msgstr ""
-"V této vzdálenosti bude server agresivně optimalizovat, které bloky pošle "
-"klientům.\n"
-"Malé hodnoty mohou mírně zvýšit rychlost, mohou však také způsobit viditelné "
-"nedostatky ve vykreslování.\n"
-"(některé bloky, zvláště pod vodou, v jeskyních a občas i na zemi, nebudou "
-"vykresleny)\n"
-"Nastavení této hodnoty na více než max_block_send_distance zakáže "
-"optimalizaci.\n"
-"Jednotkou je mapblok (16 bloků)"
+"V této vzdálenosti bude server razantně optimalizovat výběr bloků,\n"
+"které pošle klientům.\n"
+"Malé hodnoty mohou zlepšit výkon, však mohou také způsobit chyby\n"
+"ve vykreslování (některé bloky, zvláště pod vodou, v jeskyních\n"
+"a někdy i na zemi, nebudou vykresleny).\n"
+"Nastavení této hodnoty vyšší než max_block_send_distance zakáže vypne\n"
+"tuto optimalizaci.\n"
+"Jednotkou je mapblok (16 bloků)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatic forward key"
-msgstr "Vpřed"
+msgstr "Automaticky vpřed klávesa"
 
 #: src/settings_translation_file.cpp
 msgid "Automatically jump up single-node obstacles."
 msgstr "Automaticky vyskočit na překážky vysoké 1 blok."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatically report to the serverlist."
-msgstr "Automaticky hlásit seznamu serverů."
+msgstr "Automaticky nahlásit do seznamu serverů."
 
 #: src/settings_translation_file.cpp
 msgid "Autosave screen size"
@@ -2478,35 +2511,30 @@ msgid "Autoscaling mode"
 msgstr "Režim automatického přiblížení"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Klávesa skoku"
+msgstr "Aux1 klávesa"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Klávesa pro výstup/sestup"
+msgstr "Aux1 klávesa pro výstup/sestup"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
 msgstr "Vzad"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Base ground level"
-msgstr "Výška povrchu země"
+msgstr "Základní úroveň povrchu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Base terrain height."
-msgstr "Základní výška terénu"
+msgstr "Základní výška terénu."
 
 #: src/settings_translation_file.cpp
 msgid "Basic"
 msgstr "Základní"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Basic privileges"
 msgstr "Základní práva"
 
@@ -2539,24 +2567,20 @@ msgid "Block send optimize distance"
 msgstr "Optimalizace vzdálenosti vysílání bloku"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold and italic font path"
-msgstr "Cesta k neproporcionálnímu písmu"
+msgstr "Cesta k tučnému písmu s kurzívou"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold and italic monospace font path"
-msgstr "Cesta k neproporcionálnímu písmu"
+msgstr "Cesta k tučnému proporcionálnímu písmu s kurzívou"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold font path"
-msgstr "Cesta k písmu"
+msgstr "Cesta k tučnému písmu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold monospace font path"
-msgstr "Cesta k neproporcionálnímu písmu"
+msgstr "Cesta k proporcionálnímu písmu"
 
 #: src/settings_translation_file.cpp
 msgid "Build inside player"
@@ -2588,7 +2612,7 @@ msgstr "Klávesa pro přepínání aktualizace pohledu"
 
 #: src/settings_translation_file.cpp
 msgid "Cave noise"
-msgstr "Šum jeskyní"
+msgstr "Šum v jeskynních"
 
 #: src/settings_translation_file.cpp
 msgid "Cave noise #1"
@@ -2600,7 +2624,7 @@ msgstr "Šum v jeskynních 2"
 
 #: src/settings_translation_file.cpp
 msgid "Cave width"
-msgstr "Šířka jeskyně"
+msgstr "Šířka jeskyní"
 
 #: src/settings_translation_file.cpp
 msgid "Cave1 noise"
@@ -2627,48 +2651,49 @@ msgid "Cavern threshold"
 msgstr "Práh jeskynních dutin"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Cavern upper limit"
-msgstr "Limit jeskynních dutin"
+msgstr "Horní hranice jeskynních dutin"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Center of light curve boost range.\n"
 "Where 0.0 is minimum light level, 1.0 is maximum light level."
 msgstr ""
+"Střed posílené křivky světla.\n"
+"0.0 odpovídá nejnižší úrovni, 1.0 odpovídá nejvyšší úrovni světla."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Práh pouštního šumu"
+msgstr "Doba do zobrazení času pro příkaz v chatu"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
+msgid "Chat commands"
+msgstr "Příkazy"
+
+#: src/settings_translation_file.cpp
 msgid "Chat font size"
-msgstr "Velikost písma"
+msgstr "Velikost písma v chatu"
 
 #: src/settings_translation_file.cpp
 msgid "Chat key"
 msgstr "Klávesa chatu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat log level"
-msgstr "Úroveň minimální důležitosti ladících informací"
+msgstr "Úroveň důležitosti ladících informací"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message count limit"
 msgstr "Omezení počtu zpráv v Chatu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat message format"
-msgstr "Zpráva o havárii"
+msgstr "Formát zpráv v chatu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat message kick threshold"
-msgstr "Práh pouštního šumu"
+msgstr "Doba do vyhození zprávy z chatu"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message max length"
@@ -2679,8 +2704,9 @@ msgid "Chat toggle key"
 msgstr "Klávesa zobrazení chatu"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Příkazy"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Chat zobrazen"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2698,6 +2724,12 @@ msgstr "Klávesa plynulého pohybu kamery"
 msgid "Clean transparent textures"
 msgstr "Vynulovat průhledné textury"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klient"
@@ -2711,9 +2743,8 @@ msgid "Client modding"
 msgstr "Lokální mody"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Client side modding restrictions"
-msgstr "Lokální mody"
+msgstr "Omezení modování na straně klienta"
 
 #: src/settings_translation_file.cpp
 msgid "Client side node lookup range restriction"
@@ -2744,9 +2775,8 @@ msgid "Colored fog"
 msgstr "Barevná mlha"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Barevná mlha"
+msgstr "Zbarvené stíny"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2758,6 +2788,13 @@ msgid ""
 "These flags are independent from Minetest versions,\n"
 "so see a full list at https://content.minetest.net/help/content_flags/"
 msgstr ""
+"Seznam nastavení ve formátu CSV sloužící k filtrování obsahu repozitáře.\n"
+"\"nesvobodné\" slouží pro skrytí balíčků, které se podle definice Free "
+"Software Foundation\n"
+"neřadí do \"svobodného softwaru\".\n"
+"Můžete také zadat hodnocení obsahu.\n"
+"Tato nastavení jsou nezávislá na versi Minetestu,\n"
+"kompletní seznam na: https://content.minetest.net/help/content_flags/"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2780,6 +2817,22 @@ msgstr ""
 msgid "Command key"
 msgstr "CMD ⌘"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Propojené sklo"
@@ -2806,16 +2859,15 @@ msgstr "Šírka konzole"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Flag Blacklist"
-msgstr ""
+msgstr "ContentDB: Černá listina"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Max Concurrent Downloads"
-msgstr ""
+msgstr "ContentDB Max. souběžných stahování"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "ContentDB URL"
-msgstr "Pokračovat"
+msgstr "ContentDB-URL"
 
 #: src/settings_translation_file.cpp
 msgid "Continuous forward"
@@ -2826,25 +2878,26 @@ msgid ""
 "Continuous forward movement, toggled by autoforward key.\n"
 "Press the autoforward key again or the backwards movement to disable."
 msgstr ""
+"Nepřetržitý pohyb vpřed zapnutý klávesou Automaticky vpřed.\n"
+"Stisk klávesy Automaticky vpřed nebo Dozadu, pohyb zruší."
 
 #: src/settings_translation_file.cpp
 msgid "Controls"
 msgstr "Ovládání"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Controls length of day/night cycle.\n"
 "Examples:\n"
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
 "Ovládání délky denního cyklu.\n"
-"Příklad: 72 = 20 minut, 360 = 4 minutý, 1 = 24 hodin, 0 = zůstává pouze noc "
-"nebo den."
+"Příklad:\n"
+"72 = 20 minut, 360 = 4 minuty, 1 = 24 hodin, 0 = zůstává pouze noc nebo den."
 
 #: src/settings_translation_file.cpp
 msgid "Controls sinking speed in liquid."
-msgstr "Ovládá rychlost potápění v kapalinách."
+msgstr "Stanovuje rychlost potápění v kapalinách."
 
 #: src/settings_translation_file.cpp
 msgid "Controls steepness/depth of lake depressions."
@@ -2860,6 +2913,9 @@ msgid ""
 "Value >= 10.0 completely disables generation of tunnels and avoids the\n"
 "intensive noise calculations."
 msgstr ""
+"Stanovuje šířku tunelů. Nižší hodnota vytváří širší tunely.\n"
+"Hodnota >= 10.0 úplně vypne generování tunelů, čímž se zruší\n"
+"náročné výpočty šumu."
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
@@ -2877,8 +2933,10 @@ msgstr "Průhlednost zaměřovače"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
-msgstr "Průhlednost zaměřovače (mezi 0 a 255)."
+"This also applies to the object crosshair."
+msgstr ""
+"Průhlednost zaměřovače (0 až 255).\n"
+"Také určuje barvu zaměřovače"
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2889,6 +2947,8 @@ msgid ""
 "Crosshair color (R,G,B).\n"
 "Also controls the object crosshair color"
 msgstr ""
+"Barva zaměřovače (R,G,B).\n"
+"Také určuje barvu zaměřovače"
 
 #: src/settings_translation_file.cpp
 msgid "DPI"
@@ -2903,9 +2963,8 @@ msgid "Debug info toggle key"
 msgstr "Klávesa pro zobrazení ladících informací"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Debug log file size threshold"
-msgstr "Práh pouštního šumu"
+msgstr "Práh velikosti souboru s ladícími informacemi"
 
 #: src/settings_translation_file.cpp
 msgid "Debug log level"
@@ -2917,7 +2976,7 @@ msgstr "Klávesa snížení hlasitosti"
 
 #: src/settings_translation_file.cpp
 msgid "Decrease this to increase liquid resistance to movement."
-msgstr ""
+msgstr "Snižte toto pro zvýšení odporu kapalin vůči pohybu."
 
 #: src/settings_translation_file.cpp
 msgid "Dedicated server step"
@@ -2952,16 +3011,19 @@ msgid "Default report format"
 msgstr "Výchozí formát reportů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Default stack size"
-msgstr "Výchozí hra"
+msgstr "Výchozí velikost hromádky"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Určit kvalitu filtrování stínů\n"
+"Simuluje efekt měkkých stínů použitím PCF nebo Poissonova disku,\n"
+"za využívá většího výkonu."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -2972,14 +3034,12 @@ msgid "Defines areas with sandy beaches."
 msgstr "Určuje oblasti s písčitými plážemi."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines distribution of higher terrain and steepness of cliffs."
-msgstr "Určuje oblasti vyššího terénu (cliff-top) a ovlivňuje strmost útesů."
+msgstr "Určuje rozmístění vyššího terénu a strmých útesů."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines distribution of higher terrain."
-msgstr "Určuje oblasti spadající pod 'terrain_higher' (cliff-top terén)."
+msgstr "Určuje rozmístění vyššího terénu."
 
 #: src/settings_translation_file.cpp
 msgid "Defines full size of caverns, smaller values create larger caverns."
@@ -2996,28 +3056,24 @@ msgid "Defines location and terrain of optional hills and lakes."
 msgstr "Určuje pozici a terén možných hor a jezer."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the base ground level."
-msgstr "Určuje lesní oblasti a hustotu stromového porostu."
+msgstr "Určuje základní úroveň povrchu."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the depth of the river channel."
-msgstr "Určuje lesní oblasti a hustotu stromového porostu."
+msgstr "Určuje hloubku říčního koryta."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
 msgstr "Určuje maximální posun hráče v blocích (0 = neomezený)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the width of the river channel."
-msgstr "Určuje makroskopickou strukturu koryta řeky."
+msgstr "Určuje šířku říčního koryta."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the width of the river valley."
-msgstr "Určuje oblasti, kde stromy nesou plody."
+msgstr "Určuje šířku údolí řeky."
 
 #: src/settings_translation_file.cpp
 msgid "Defines tree areas and tree density."
@@ -3045,13 +3101,12 @@ msgid "Deprecated Lua API handling"
 msgstr "Zacházení se zastaralým Lua API"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Depth below which you'll find giant caverns."
-msgstr "Hloubka pod kterou najdete velké jeskyně."
+msgstr "Hloubka, pod kterou se nachází velké jeskynní dutiny."
 
 #: src/settings_translation_file.cpp
 msgid "Depth below which you'll find large caves."
-msgstr "Hloubka pod kterou najdete velké jeskyně."
+msgstr "Hloubka, pod kterou se nachází velké jeskyně."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3066,22 +3121,20 @@ msgid "Desert noise threshold"
 msgstr "Práh pouštního šumu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Deserts occur when np_biome exceeds this value.\n"
 "When the 'snowbiomes' flag is enabled, this is ignored."
 msgstr ""
 "Pouště se objeví v místech, kde 'np_biome' přesahuje tuto hodnotu.\n"
-"Pokud je zapnutý nový systém biomů, toto nastavení nemá vliv."
+"Ignorováno, pokud je zapnuté nastavení \"snowbiomes\"."
 
 #: src/settings_translation_file.cpp
 msgid "Desynchronize block animation"
 msgstr "Nesynchronizovat animace bloků"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dig key"
-msgstr "Klávesa doprava"
+msgstr "Klávesa těžení"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3095,6 +3148,10 @@ msgstr "Vypnout anticheat"
 msgid "Disallow empty passwords"
 msgstr "Zakázat prázdná hesla"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Doménové jméno serveru zobrazované na seznamu serverů."
@@ -3112,28 +3169,28 @@ msgid "Drop item key"
 msgstr "Klávesa vyhození předmětu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dump the mapgen debug information."
-msgstr "Vypsat ladící informace mapgenu."
+msgstr "Vypsat ladící informace z Generátoru mapy."
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon maximum Y"
-msgstr ""
+msgstr "Horní hranice Y pro žaláře"
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon minimum Y"
-msgstr ""
+msgstr "Dolní hranice Y pro žaláře"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dungeon noise"
-msgstr "Šum hřbetů"
+msgstr "Šum žalářů"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable IPv6 support (for both client and server).\n"
 "Required for IPv6 connections to work at all."
 msgstr ""
+"Zapnout podporu IPv6 (pro klienta i server).\n"
+"Požadováno pro IPv6 připojení."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3144,29 +3201,41 @@ msgstr ""
 "Tato funkce je experimentální a její API se může změnit."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Zapnout filtrování Poissoným diskem.\n"
+"Pokud je zapnuto, využívá Poissonův disk pro generování \"měkkých stínů\". V "
+"opačném případě je využito filtrování PCF."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Enable colored shadows. \n"
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Zanout zbarvené stíny.\n"
+"Po zapnutí vrhají průhledné předměty zbarvené stíny. Toto má velký vliv na "
+"výkon."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
 msgstr "Povolit konzolové okno"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable creative mode for all players"
-msgstr "Zapnout kreativní mód pro nové mapy."
+msgstr "Zapnout kreativní mód pro všechny hráče"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable joysticks"
 msgstr "Zapnout joysticky"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable mod channels support."
-msgstr "Zapnout zabezpečení módů"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Enable mod security"
@@ -3176,26 +3245,21 @@ msgstr "Zapnout zabezpečení módů"
 msgid "Enable players getting damage and dying."
 msgstr "Povolit zraňování a umírání hráčů."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Povolit náhodný uživatelský vstup (pouze pro testování)."
 
 #: src/settings_translation_file.cpp
 msgid "Enable register confirmation"
-msgstr ""
+msgstr "Zapnout potvrzení registrace"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable register confirmation when connecting to server.\n"
 "If disabled, new account will be registered automatically."
 msgstr ""
+"Zapnout potvrzení registrace pro připojení na server.\n"
+"Pokud je toto vypnuto, je nový účet registrován automaticky."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3234,6 +3298,8 @@ msgid ""
 "Enable vertex buffer objects.\n"
 "This should greatly improve graphics performance."
 msgstr ""
+"Zapnout objekty vyrovnávací paměti vertexů.\n"
+"Toto by mělo výrazně zlepšit grafický výkon."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3244,15 +3310,14 @@ msgstr ""
 "Např.: 0 pro žádné, 1.0 pro normální a 2.0 pro dvojité klepání."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Enable/disable running an IPv6 server.\n"
 "Ignored if bind_address is set.\n"
 "Needs enable_ipv6 to be enabled."
 msgstr ""
-"Povolit/zakázat spouštění IPv6 serveru. IPv6 server může podle\n"
-"systémového nastevení být omezen pouze na klienty s IPv6.\n"
-"Nemá vliv, pokud je 'bind_address' nastaveno."
+"Povolit/zakázat spuštění IPv6 serveru.\n"
+"Ignorováno, pokud je 'bind_address' nastaveno.\n"
+"Je třeba mít povoleno enable_ipv6."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3261,6 +3326,10 @@ msgid ""
 "appearance of high dynamic range images. Mid-range contrast is slightly\n"
 "enhanced, highlights and shadows are gradually compressed."
 msgstr ""
+"Zapíná Hableho \"Uncharted 2\" filmové mapování odstínů.\n"
+"Simuluje křivku odstínu fotografického filmu a tím přibližný vzhled\n"
+"obrázků s vysokým dynamickým rozsahem (HDR). Kontrast středních\n"
+"hodnot je lehce zvýšený, vysoké a nízké hodnoty jsou postupně komprimovány."
 
 #: src/settings_translation_file.cpp
 msgid "Enables animation of inventory items."
@@ -3281,6 +3350,16 @@ msgid ""
 "sound controls will be non-functional.\n"
 "Changing this setting requires a restart."
 msgstr ""
+"Zapíná zvukový systém.\n"
+"Vypnutí má za náledek úplné ztlumení všech zvuků\n"
+"a zvukového ovládání ve hře.\n"
+"Změna tohoto nastavení vyžaduje restart."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
@@ -3299,10 +3378,16 @@ msgid ""
 "Values < 1.0 (for example 0.25) create a more defined surface level with\n"
 "flatter lowlands, suitable for a solid floatland layer."
 msgstr ""
+"Exponent pro zužování létajících ostrovů. Mění míru zúžení.\n"
+"Hodnota = 1.0 vytvoří rovnoměrné přímé zúžení.\n"
+"Hodnoty > 1.0 vytvoří hladké zúžení vhodné pro výchozí oddělené\n"
+"létající ostrovy.\n"
+"Hodnoty < 1.0 (např. 0.25) vytvoří výraznější úroveň povrchu\n"
+"s rovinatějšími nížinami, vhodné pro souvislou vrstvu létajících ostrovů."
 
 #: src/settings_translation_file.cpp
 msgid "FPS when unfocused or paused"
-msgstr ""
+msgstr "Snímky za sekundu (FPS) při pauze či hře běžící na pozadí"
 
 #: src/settings_translation_file.cpp
 msgid "FSAA"
@@ -3317,9 +3402,8 @@ msgid "Fall bobbing factor"
 msgstr "Součinitel houpání pohledu při pádu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Fallback font path"
-msgstr "Záložní písmo"
+msgstr "Cesta k záložnímu písmu"
 
 #: src/settings_translation_file.cpp
 msgid "Fast key"
@@ -3338,12 +3422,11 @@ msgid "Fast movement"
 msgstr "Turbo režim pohybu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Turbo režim pohybu (pomocí klávesy použít).\n"
+"Turbo režim pohybu (pomocí klávesy \"Aux1\").\n"
 "Vyžaduje na serveru přidělené právo \"fast\"."
 
 #: src/settings_translation_file.cpp
@@ -3355,17 +3438,15 @@ msgid "Field of view in degrees."
 msgstr "Úhel pohledu ve stupních."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "File in client/serverlist/ that contains your favorite servers displayed in "
 "the\n"
 "Multiplayer Tab."
 msgstr ""
 "Soubor v client/serverlist/, který obsahuje oblíbené servery zobrazené na "
-"záložce 'Online hra'."
+"záložce 'Multiplayer'."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Filler depth"
 msgstr "Hloubka výplně"
 
@@ -3378,7 +3459,6 @@ msgid "Filmic tone mapping"
 msgstr "Filmový tone mapping"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3386,20 +3466,19 @@ msgid ""
 "at texture load time. This is automatically enabled if mipmapping is enabled."
 msgstr ""
 "Okraje filtrovaných textur se mohou mísit s průhlednými sousedními pixely,\n"
-"které PNG optimizery obvykle zahazují. To může vyústit v tmavý nebo světlý\n"
-"lem okolo hran. Zapnutí tohoto filtru problém řeší při načítání textur."
+"které PNG optimizery obvykle zahazují. To může vyústit v tmavé nebo světlé\n"
+"okraje  hran. Zapnutí tohoto filtru problém řeší při načítání textur.\n"
+"Toto nastavení je automaticky zapnuto, pokud je povoleno Mip-Mapování."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
 msgstr "Filtrování"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "First of 4 2D noises that together define hill/mountain range height."
-msgstr "První ze dvou 3D šumů, které dohromady definují tunely."
+msgstr "První ze 4 2D šumů, které dohromady definují rozsah výšek kopců/hor."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "First of two 3D noises that together define tunnels."
 msgstr "První ze dvou 3D šumů, které dohromady definují tunely."
 
@@ -3409,42 +3488,35 @@ msgstr "Fixované seedové čislo"
 
 #: src/settings_translation_file.cpp
 msgid "Fixed virtual joystick"
-msgstr ""
+msgstr "Nepohyblivý virtuální joystick"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland density"
-msgstr "Koncentrace hor na létajících ostrovech"
+msgstr "Hustota létajících ostrovů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland maximum Y"
-msgstr "Výška hor na létajících ostrovech"
+msgstr "Létajících ostrovy: Max. Y"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland minimum Y"
-msgstr "Výška hor na létajících ostrovech"
+msgstr "Létajících ostrovy: Min. Y"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland noise"
-msgstr "Základní šum létajících ostrovů"
+msgstr "Šum létajících ostrovů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland taper exponent"
-msgstr "Koncentrace hor na létajících ostrovech"
+msgstr "Exponent zúžení létajících ostrovů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland tapering distance"
-msgstr "Základní šum létajících ostrovů"
+msgstr "Vzdálenost zužování létajících ostrovů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland water level"
-msgstr "Výška létajících ostrovů"
+msgstr "Hladina vody na létajících ostrovech"
 
 #: src/settings_translation_file.cpp
 msgid "Fly key"
@@ -3459,7 +3531,6 @@ msgid "Fog"
 msgstr "Mlha"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Fog start"
 msgstr "Začátek mlhy"
 
@@ -3469,11 +3540,11 @@ msgstr "Klávesa pro přepnutí mlhy"
 
 #: src/settings_translation_file.cpp
 msgid "Font bold by default"
-msgstr ""
+msgstr "Tučné písmo jako výchozí"
 
 #: src/settings_translation_file.cpp
 msgid "Font italic by default"
-msgstr ""
+msgstr "Kurzíva jako výchozí"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow"
@@ -3488,18 +3559,37 @@ msgid "Font size"
 msgstr "Velikost písma"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr ""
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Velikost výchozího písma v bodech (pt)."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Velikost proporcionálního písma v bodech (pt)."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Font size of the recent chat text and chat prompt in point (pt).\n"
 "Value 0 will use the default font size."
 msgstr ""
+"Velikost písma posledního textu a výzvy v chatu v bodech (pt).\n"
+"Výchozí velikost písma se nastaví hodnotou 0."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3507,6 +3597,8 @@ msgid ""
 "placeholders:\n"
 "@name, @message, @timestamp (optional)"
 msgstr ""
+"Formát hráčovy zprávy v chatu. Řetězec níže obsahuje platné zástupce:\n"
+"@name, @message, @timestamp (optional)"
 
 #: src/settings_translation_file.cpp
 msgid "Format of screenshots."
@@ -3514,50 +3606,45 @@ msgstr "Formát snímků obrazovky."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Color"
-msgstr ""
+msgstr "Konzole Výchozí barva pozadí"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Opacity"
-msgstr ""
+msgstr "Konzole Výchozí průhlednost pozadí"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Color"
-msgstr ""
+msgstr "Konzole Barva pozadí při zobrazení na celé obrazovce"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Opacity"
-msgstr ""
+msgstr "Konzole Průhlednost pozadí při zobrazení na celé obrazovce"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Formspec default background color (R,G,B)."
-msgstr "Barva (R,G,B) pozadí herní chatovací konzole."
+msgstr "Konzole Výchozí barva pozadí (R,G,B)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Formspec default background opacity (between 0 and 255)."
-msgstr ""
-"Průhlednost pozadí herní chatovací konzole (neprůhlednost, mezi 0 a 255)."
+msgstr "Konzole Výchozí průhlednost pozadí (0 až 255)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Formspec full-screen background color (R,G,B)."
-msgstr "Barva (R,G,B) pozadí herní chatovací konzole."
+msgstr "Konzole Barva pozadí při zobrazení na celou obrazovku (R,G,B)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Formspec full-screen background opacity (between 0 and 255)."
 msgstr ""
-"Průhlednost pozadí herní chatovací konzole (neprůhlednost, mezi 0 a 255)."
+"Konzole Průhlednost pozadí při zobrazení na celou obrazovku (0 až 255)."
 
 #: src/settings_translation_file.cpp
 msgid "Forward key"
 msgstr "Vpřed"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Fourth of 4 2D noises that together define hill/mountain range height."
-msgstr "První ze dvou 3D šumů, které dohromady definují tunely."
+msgstr ""
+"Čtvrtý ze čtyř 2D šumů, které dohromady definují rozsah výšek kopců/hor."
 
 #: src/settings_translation_file.cpp
 msgid "Fractal type"
@@ -3567,25 +3654,20 @@ msgstr "Typ fraktálu"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Podíl viditelné vzdálenosti, na kterém začne být mlha vykreslována"
 
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid "FreeType fonts"
-msgstr "Písma Freetype"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
 "nodes)."
 msgstr ""
-"Maximální vzdálenost, ve které jsou klientům generovány bloky, určená\n"
-"v mapblocích (16 bloků)."
+"Vzdálenost, ve které jsou klientům generovány bloky, určená v mapblocích (16 "
+"bloků)."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are sent to clients, stated in mapblocks (16 nodes)."
 msgstr ""
-"Maximální vzdálenost, ve které jsou klientům odeslány bloky, určená\n"
-"v mapblocích (16 bloků)."
+"Vzdálenost, ze které jsou klientům odesílány bloky, určená v mapblocích (16 "
+"bloků)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3595,6 +3677,11 @@ msgid ""
 "to maintain active objects up to this distance in the direction the\n"
 "player is looking. (This can avoid mobs suddenly disappearing from view)"
 msgstr ""
+"Vzdálenost, na kterou má klient inforamace o objektech,\n"
+"určená v mapblocích (16 bloků).\n"
+"Nastavení této hodnoty výše než active_block_range umožní serveru\n"
+"udržet v paměti aktivní objekty až do této vzdálenosti ve směru hráčova\n"
+"pohledu. (Toto může předejít náhlému mizení postav)"
 
 #: src/settings_translation_file.cpp
 msgid "Full screen"
@@ -3625,26 +3712,28 @@ msgstr "Globální callback funkce"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Globální parametry generování mapy.\n"
-"V mapgenu v6 ovládal příznak 'decorations' všechny dekorace kromě\n"
-"stromů a tropické trávy. V ostatních mapgenech tento příznak řídí\n"
-"všechny dekorace.\n"
-"Neuvedené příznaky zůstávají ve výchozím stavu.\n"
-"Příznaky začínající na 'no' slouží k zakázání možnosti."
+"V Generátoru mapy v6 ovládá nastavení \"decorations\" všechny dekorace\n"
+"kromě stromů a tropické trávy, ve všech ostatních verzích Generátoru mapy\n"
+"ovládá toto nastavení všechny dekorace."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Gradient of light curve at maximum light level.\n"
 "Controls the contrast of the highest light levels."
 msgstr ""
+"Gradient křivky světla na nejvyšší úrovni světla.\n"
+"Určuje kontrast nejvyšších světelných hodnot."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Gradient of light curve at minimum light level.\n"
 "Controls the contrast of the lowest light levels."
 msgstr ""
+"Gradient křivky světla na nejnižší úrovni světla.\n"
+"Určuje kontrast nejnižších světelných hodnot."
 
 #: src/settings_translation_file.cpp
 msgid "Graphics"
@@ -3659,14 +3748,12 @@ msgid "Ground level"
 msgstr "Výška povrchu země"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Ground noise"
-msgstr "Výška povrchu země"
+msgstr "Šum povrchu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "HTTP mods"
-msgstr "HTTP mody"
+msgstr "HTTP režimy"
 
 #: src/settings_translation_file.cpp
 msgid "HUD scale factor"
@@ -3677,7 +3764,6 @@ msgid "HUD toggle key"
 msgstr "Klávesa pro přepnutí HUD (Head-Up Display)"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Handling for deprecated Lua API calls:\n"
 "-    none: Do not log deprecated calls\n"
@@ -3685,7 +3771,7 @@ msgid ""
 "-    error: abort on usage of deprecated call (suggested for mod developers)."
 msgstr ""
 "Zacházení s voláními zastaralého Lua API:\n"
-"-    legacy: pokusí se napodobit staré chování (výchozí pro release).\n"
+"-    none: Nezaznamenávat zastaralá volání\n"
 "-    log: pokusí se napodobit staré chování a zaznamená backtrace volání\n"
 "     (výchozí pro debug).\n"
 "-    error: při volání zastaralé funkce skončit (doporučeno vývojářům modů)."
@@ -3712,10 +3798,11 @@ msgid "Heat noise"
 msgstr "Tepelný šum"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Výšková část počáteční velikosti okna."
+msgstr ""
+"Výškový parametr počáteční velikosti okna. Ignorováno v režimu na celé "
+"obrazovce."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3734,24 +3821,20 @@ msgid "Hill threshold"
 msgstr "Práh kopců"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hilliness1 noise"
-msgstr "Tepelný šum"
+msgstr "Šum kopcovitosti1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hilliness2 noise"
-msgstr "Tepelný šum"
+msgstr "Šum kopcovitosti2"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hilliness3 noise"
-msgstr "Tepelný šum"
+msgstr "Šum kopcovitosti3"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hilliness4 noise"
-msgstr "Tepelný šum"
+msgstr "Šum kopcovitosti4"
 
 #: src/settings_translation_file.cpp
 msgid "Homepage of server, to be displayed in the serverlist."
@@ -3762,18 +3845,24 @@ msgid ""
 "Horizontal acceleration in air when jumping or falling,\n"
 "in nodes per second per second."
 msgstr ""
+"Horizontální zrychlení ve vzduchu při skoku nebo pádu,\n"
+"určeno v blocích za sekundu za sekundu."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Horizontal and vertical acceleration in fast mode,\n"
 "in nodes per second per second."
 msgstr ""
+"Horizontální a vertikální zrychlení v rychlém režimu,\n"
+"určeno v blocích za sekundu za sekundu."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Horizontal and vertical acceleration on ground or when climbing,\n"
 "in nodes per second per second."
 msgstr ""
+"Horizontální a vertikální zrychlení na zemi nebo při lezení,\n"
+"určeno v blocích za sekundu za sekundu."
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar next key"
@@ -3784,169 +3873,136 @@ msgid "Hotbar previous key"
 msgstr "Klávesa pro předchozí věc v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 1 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 1 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 10 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 10 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 11 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 11 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 12 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 12 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 13 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 13 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 14 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 14 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 15 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 15 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 16 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 16 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 17 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 17 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 18 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 18 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 19 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 19 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 2 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 2 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 20 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 20 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 21 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 21 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 22 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 22 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 23 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 23 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 24 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 24 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 25 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 25 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 26 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 26 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 27 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 27 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 28 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 28 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 29 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 29 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 3 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 3 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 30 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 30 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 31 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 31 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 32 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 32 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 4 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 4 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 5 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 5 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 6 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 6 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 7 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 7 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 8 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 8 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar slot 9 key"
-msgstr "Klávesa pro následující věc v liště předmětů"
+msgstr "Klávesa pro přihrádku 9 v liště předmětů"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "How deep to make rivers."
-msgstr "Jak hluboké dělat řeky"
+msgstr "Jak hluboké dělat řeky."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3954,6 +4010,9 @@ msgid ""
 "If negative, liquid waves will move backwards.\n"
 "Requires waving liquids to be enabled."
 msgstr ""
+"Rychlost pohybu vln v kapalinách. Vyšší = rychlejší.\n"
+"Záporné hodnoty vytvoří vlny jdoucí pozpátku.\n"
+"Vyžaduje zapnuté vlnění kapalin."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3964,9 +4023,8 @@ msgstr ""
 "Vyšší hodnota zlepší rychlost programu, ale také způsobí větší spotřebu RAM."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "How wide to make rivers."
-msgstr "Jak široké dělat řeky"
+msgstr "Jak široké dělat řeky."
 
 #: src/settings_translation_file.cpp
 msgid "Humidity blend noise"
@@ -3997,14 +4055,12 @@ msgstr ""
 "omezit ji vyčkáváním, aby se zbytečně neplýtvalo výkonem CPU."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"V zakázaném stavu způsobí, že klávesa \"použít\" je použita k aktivaci "
-"turba\n"
-"v režimu létání."
+"Pokud je vypnuto, klávesa \"Aux1\" je , při zapnutém létání\n"
+"a rychlém režimu, použita k rychlému létání."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4030,14 +4086,13 @@ msgstr ""
 "K tomu je potřeba mít na serveru oprávnění \"noclip\"."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Když zapnuto, místo klávesy \"plížit se\" se ke slézání a potápění používá "
-"klávese \"použít\"."
+"Pokud je zapnuto, je klávesa \"Aux1\" využita pro sestup\n"
+"namísto klávesy \"Plížení\"."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4064,6 +4119,8 @@ msgid ""
 "If enabled, makes move directions relative to the player's pitch when flying "
 "or swimming."
 msgstr ""
+"Pokud je zapnuto, je směr pohybu, při létání nebo plavání, závislý na úhlu "
+"hráčova pohledu."
 
 #: src/settings_translation_file.cpp
 msgid "If enabled, new players cannot join with an empty password."
@@ -4085,12 +4142,16 @@ msgid ""
 "limited\n"
 "to this distance from the player to the node."
 msgstr ""
+"Pokud je omezení CSM pro vzdálenost bloků povoleno, jsou volání get_node\n"
+"omezena na tuto vzdálenost hráče od bloku."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Pokud je doba výkonu příkazu z chatu delší než zadaný čas v sekundách,\n"
+"přidej informaci o čase do příkazu v chatu"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4099,6 +4160,11 @@ msgid ""
 "deleting an older debug.txt.1 if it exists.\n"
 "debug.txt is only moved if this setting is positive."
 msgstr ""
+"Pokud velikost souboru debug.txt po otevření přesáhne počet megabytů určený\n"
+"tímto nastavením, bude soubor přesunut do debug.txt.1 (toto vymaže původní "
+"debug.txt.1,\n"
+"pokud existuje).\n"
+"debug.txt je přesunut pouze pokud je toto nastavení platné."
 
 #: src/settings_translation_file.cpp
 msgid "If this is set, players will always (re)spawn at the given position."
@@ -4114,8 +4180,7 @@ msgstr "Ve hře"
 
 #: src/settings_translation_file.cpp
 msgid "In-game chat console background alpha (opaqueness, between 0 and 255)."
-msgstr ""
-"Průhlednost pozadí herní chatovací konzole (neprůhlednost, mezi 0 a 255)."
+msgstr "Průhlednost pozadí herní chatovací konzole (neprůhlednost, 0 až 255)."
 
 #: src/settings_translation_file.cpp
 msgid "In-game chat console background color (R,G,B)."
@@ -4133,7 +4198,7 @@ msgstr "Klávesa zvýšení hlasitosti"
 
 #: src/settings_translation_file.cpp
 msgid "Initial vertical speed when jumping, in nodes per second."
-msgstr ""
+msgstr "Počáteční vertikální rychlost skoku v blocích za sekundu."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4144,7 +4209,8 @@ msgstr ""
 "Obvykle využíváno jen vývojáři jádra/builtin"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Instrumentovat chatovací přikazy při registraci."
 
 #: src/settings_translation_file.cpp
@@ -4198,14 +4264,12 @@ msgid "Invert vertical mouse movement."
 msgstr "Obrátit svislý pohyb myši."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Italic font path"
-msgstr "Cesta k neproporcionálnímu písmu"
+msgstr "Cesta k písmu s kurzívou"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Italic monospace font path"
-msgstr "Cesta k neproporcionálnímu písmu"
+msgstr "Cesta k proporcionálnímu písmu s kurzívou"
 
 #: src/settings_translation_file.cpp
 msgid "Item entity TTL"
@@ -4222,6 +4286,10 @@ msgid ""
 "increases processing load.\n"
 "At iterations = 20 this mapgen has a similar load to mapgen V7."
 msgstr ""
+"Opakování rekurzivní funkce.\n"
+"Zvýšení hodnoty vede ke zlepšení detailů, ale také zvyšuje nároky na výkon.\n"
+"Při opakování = 20 má tento Generátor mapy podobné nároky jako\n"
+"Generátor mapy v7."
 
 #: src/settings_translation_file.cpp
 msgid "Joystick ID"
@@ -4233,20 +4301,18 @@ msgstr "Interval opakování tlačítek joysticku"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
-msgstr "Typ joysticku"
+msgid "Joystick dead zone"
+msgstr "Mrtvá zóna joysticku"
 
 #: src/settings_translation_file.cpp
 msgid "Joystick frustum sensitivity"
 msgstr "Citlivost otáčení pohledu joystickem"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Joystick type"
 msgstr "Typ joysticku"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Julia set only.\n"
 "W component of hypercomplex constant.\n"
@@ -4254,44 +4320,47 @@ msgid ""
 "Has no effect on 3D fractals.\n"
 "Range roughly -2 to 2."
 msgstr ""
-"Julia udává jen: W komponet hyperkomplexu konstantní určení tvaru Julie.\n"
-"Nemá efekt na 3D fraktálech.\n"
-"Rozsah zhruba -2 až 2."
+"Pouze pro set Julia.\n"
+"Komponenta W hyperkomplexní konstanty.\n"
+"Mění tvar fraktálu.\n"
+"Nemá žádný vliv na 3D fraktály.\n"
+"Rozmezí přibližně -2 až 2."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Julia set only.\n"
 "X component of hypercomplex constant.\n"
 "Alters the shape of the fractal.\n"
 "Range roughly -2 to 2."
 msgstr ""
-"Julia udává jen: komponet X hyperkomplexu konstantího udávání tvaru julie.\n"
-"Rozsah zhruba -2 až 2."
+"Pouze pro set Julia.\n"
+"Komponenta X hyperkomplexní konstanty.\n"
+"Mění tvar fraktálu.\n"
+"Rozmezí přibližně -2 až 2."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Julia set only.\n"
 "Y component of hypercomplex constant.\n"
 "Alters the shape of the fractal.\n"
 "Range roughly -2 to 2."
 msgstr ""
-"Julia udává jen: W komponet hyperkomplexu konstantní určení tvaru Julie.\n"
-"Nemá efekt na 3D fraktálech.\n"
-"Rozsah zhruba -2 až 2."
+"Pouze pro set Julia.\n"
+"Komponenta Y hyperkomplexní konstanty.\n"
+"Mění tvar fraktálu.\n"
+"Rozmezí přibližně -2 až 2."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Julia set only.\n"
 "Z component of hypercomplex constant.\n"
 "Alters the shape of the fractal.\n"
 "Range roughly -2 to 2."
 msgstr ""
-"Julia udává jen: W komponet hyperkomplexu konstantní určení tvaru Julie.\n"
-"Nemá efekt na 3D fraktálech.\n"
-"Rozsah zhruba -2 až 2."
+"Pouze pro set Julia.\n"
+"Komponenta Z hyperkomplexní konstanty.\n"
+"Mění tvar fraktálu.\n"
+"Rozmezí přibližně -2 až 2."
 
 #: src/settings_translation_file.cpp
 msgid "Julia w"
@@ -4338,13 +4407,12 @@ msgstr ""
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Key for digging.\n"
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"klávesy pro snížení hlasitosti.\n"
+"Klávesa pro těžení\n"
 "viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4374,6 +4442,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro zvýšení hlasitosti\n"
+"viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4381,6 +4452,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro skok.\n"
+"viz. See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4388,16 +4462,19 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro rychlý pohyb v rychlém režimu.\n"
+"viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Key for moving the player backward.\n"
 "Will also disable autoforward, when active.\n"
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Klávesa pro odhození právě drženého předmětu.\n"
+"Klávesa pro pohyb hráče zpět.\n"
+"Také vypne automatický pohyb vpřed, pokud je zapnutý.\n"
 "viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4407,6 +4484,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro pohyb hráče vpřed.\n"
+"viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4414,6 +4494,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro pohyb hráče doleva.\n"
+"viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4421,6 +4504,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro pohyb hráče doprava.\n"
+"viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4428,6 +4514,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro ztlumení hry.\n"
+"viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4435,6 +4524,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Klávesa pro otevření okna chatu za účelem zadání příkazů.\n"
+"viz. http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4987,15 +5079,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Kick players who sent more than X messages per 10 seconds."
-msgstr ""
+msgstr "Vyhodit hráče, který poslal více jak X zpráv během 10 sekund."
 
 #: src/settings_translation_file.cpp
 msgid "Lake steepness"
-msgstr ""
+msgstr "Strmost jezer"
 
 #: src/settings_translation_file.cpp
 msgid "Lake threshold"
-msgstr ""
+msgstr "Strmost jezer"
 
 #: src/settings_translation_file.cpp
 msgid "Language"
@@ -5003,19 +5095,19 @@ msgstr "Jazyk"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave depth"
-msgstr "Hloubka velké jeskynÄ\9b"
+msgstr "Hloubka velkých jeskyní"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave maximum number"
-msgstr ""
+msgstr "Horní hranice velkých jeskyní"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave minimum number"
-msgstr ""
+msgstr "Spodní hranice velkých jeskyní"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave proportion flooded"
-msgstr ""
+msgstr "Poměr zatopení velkých jeskyní"
 
 #: src/settings_translation_file.cpp
 msgid "Large chat console key"
@@ -5032,6 +5124,11 @@ msgid ""
 "-   Simple: only outer faces, if defined special_tiles are used\n"
 "-   Opaque: disable transparency"
 msgstr ""
+"Styl listí:\n"
+"-   Vícevrstevné: všechny plochy jsou viditelné\n"
+"-   Jednoduché: pouze vnější plochy, pokud je definováno special_tiles, jsou "
+"použity\n"
+"-   Neprůhledné: vypne průhlednost"
 
 #: src/settings_translation_file.cpp
 msgid "Left key"
@@ -5043,24 +5140,28 @@ msgid ""
 "updated over\n"
 "network."
 msgstr ""
+"Frekvence aktualizece objektů na serveru.\n"
+"Určeno v délce jedné periody."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Length of liquid waves.\n"
 "Requires waving liquids to be enabled."
 msgstr ""
+"Délka vln v kapalinách.\n"
+"Vyžaduje zapnuté vlnění kapalin."
 
 #: src/settings_translation_file.cpp
 msgid "Length of time between Active Block Modifier (ABM) execution cycles"
-msgstr ""
+msgstr "Frekvence vykonání cyklů Active Block Modifieru (ABM)"
 
 #: src/settings_translation_file.cpp
 msgid "Length of time between NodeTimer execution cycles"
-msgstr ""
+msgstr "Frekvence vykonání cyklů ČasovačeBloku"
 
 #: src/settings_translation_file.cpp
 msgid "Length of time between active block management cycles"
-msgstr ""
+msgstr "Frekvence vykonání cyklů aktivní správy bloků"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5073,30 +5174,38 @@ msgid ""
 "-    info\n"
 "-    verbose"
 msgstr ""
+"Úroveň ladících informací zapsaných do debug.txt:\n"
+"-    <nothing> (žádné ladící informace)\n"
+"-    none (zprávy budou vypsány bez patřičné úrovně)\n"
+"-    error (chyba)\n"
+"-    warning (varování)\n"
+"-    action (akce)\n"
+"-    info (informace)\n"
+"-    verbose (slovně)"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve boost"
-msgstr ""
+msgstr "Posílení křivky světla"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve boost center"
-msgstr ""
+msgstr "Posílení křivky světla Středy"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve boost spread"
-msgstr ""
+msgstr "Posílení křivky světla Šíření"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve gamma"
-msgstr ""
+msgstr "Křivka světla Gamma"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve high gradient"
-msgstr ""
+msgstr "Křivka světla Vysoký gradient"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve low gradient"
-msgstr ""
+msgstr "Křivka světla Nízký gradient"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5104,6 +5213,9 @@ msgid ""
 "Only mapchunks completely within the mapgen limit are generated.\n"
 "Value is stored per-world."
 msgstr ""
+"Limit generování mapy v blocích, ve všech 6 směrech od (0,0,0).\n"
+"Generují se pouze kusy nacházející se kompletně v zadaném limitu.\n"
+"Tato hodnota je unikátní pro každý svět."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5113,39 +5225,43 @@ msgid ""
 "-    Downloads performed by main menu (e.g. mod manager).\n"
 "Only has an effect if compiled with cURL."
 msgstr ""
+"Omezuje počet paralelních HTTP požadavků. Má vliv na:\n"
+"-    Načítání multimédií, pokud server používá nastavení remote_media.\n"
+"-    Stahování seznamu serverů a oznámení na serveru.\n"
+"-    Stahování prováděná přes hlavní nabídku (např. Správce modů).\n"
+"Má vliv pouze v případě kompilace přes cURL."
 
 #: src/settings_translation_file.cpp
 msgid "Liquid fluidity"
-msgstr ""
+msgstr "Tekutost kapalin"
 
 #: src/settings_translation_file.cpp
 msgid "Liquid fluidity smoothing"
-msgstr ""
+msgstr "Vyhlazení tekutosti kapalin"
 
 #: src/settings_translation_file.cpp
 msgid "Liquid loop max"
-msgstr ""
+msgstr "Horní hranice kapalinového cyklu"
 
 #: src/settings_translation_file.cpp
 msgid "Liquid queue purge time"
-msgstr ""
+msgstr "Doba vymazání fronty kapalin"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Liquid sinking"
-msgstr "Rychlost sestupu"
+msgstr "Rychlost stékání kapalin"
 
 #: src/settings_translation_file.cpp
 msgid "Liquid update interval in seconds."
-msgstr ""
+msgstr "Frekvence aktualizace kapalin v sekundách."
 
 #: src/settings_translation_file.cpp
 msgid "Liquid update tick"
-msgstr ""
+msgstr "Jeden cyklus aktualizace kapalin"
 
 #: src/settings_translation_file.cpp
 msgid "Load the game profiler"
-msgstr ""
+msgstr "Načíst profilování hry"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5153,19 +5269,21 @@ msgid ""
 "Provides a /profiler command to access the compiled profile.\n"
 "Useful for mod developers and server operators."
 msgstr ""
+"Načíst profilování hry pro sběr profilovacích dat.\n"
+"Umožňuje použít příkaz /profiler pro přístup ke zkopilovanému profilu.\n"
+"Užitečné pro vývojáře modů a provozovatele serverů."
 
 #: src/settings_translation_file.cpp
 msgid "Loading Block Modifiers"
-msgstr ""
+msgstr "Loading Block Modifiery"
 
 #: src/settings_translation_file.cpp
 msgid "Lower Y limit of dungeons."
-msgstr ""
+msgstr "Spodní hranice Y pro žaláře."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Lower Y limit of floatlands."
-msgstr "Maximální počet emerge front"
+msgstr "Spodní hranice Y pro létající ostrovy."
 
 #: src/settings_translation_file.cpp
 msgid "Main menu script"
@@ -5175,53 +5293,46 @@ msgstr "Skript hlavní nabídky"
 msgid ""
 "Make fog and sky colors depend on daytime (dawn/sunset) and view direction."
 msgstr ""
+"Barva mlhy a oblohy záleží na denní době (svítání/soumrak) a na směru "
+"pohledu."
 
 #: src/settings_translation_file.cpp
 msgid "Makes all liquids opaque"
-msgstr ""
+msgstr "Udělá všechny kapaliny neprůhledné"
 
 #: src/settings_translation_file.cpp
 msgid "Map Compression Level for Disk Storage"
-msgstr ""
+msgstr "Úroveň komprese mapy pro pevné úložiště"
 
 #: src/settings_translation_file.cpp
 msgid "Map Compression Level for Network Transfer"
-msgstr ""
+msgstr "Úroveň komprese mapy pro přenost internetem"
 
 #: src/settings_translation_file.cpp
 msgid "Map directory"
-msgstr ""
+msgstr "Směr mapy"
 
 #: src/settings_translation_file.cpp
 msgid "Map generation attributes specific to Mapgen Carpathian."
-msgstr ""
+msgstr "Parametry generování mapy pro Generátor mapy - Carpathian."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen Flat.\n"
 "Occasional lakes and hills can be added to the flat world."
 msgstr ""
-"Globální parametry generování mapy.\n"
-"V mapgenu v6 ovládal příznak 'decorations' všechny dekorace kromě\n"
-"stromů a tropické trávy. V ostatních mapgenech tento příznak řídí\n"
-"všechny dekorace.\n"
-"Neuvedené příznaky zůstávají ve výchozím stavu.\n"
-"Příznaky začínající na 'no' slouží k zakázání možnosti."
+"Parametry generování mapy pro Generátor mapy - Plocha.\n"
+"Do plochého světa je možné přidat občasná jezera a kopce."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen Fractal.\n"
 "'terrain' enables the generation of non-fractal terrain:\n"
 "ocean, islands and underground."
 msgstr ""
-"Globální parametry generování mapy.\n"
-"V mapgenu v6 ovládal příznak 'decorations' všechny dekorace kromě\n"
-"stromů a tropické trávy. V ostatních mapgenech tento příznak řídí\n"
-"všechny dekorace.\n"
-"Neuvedené příznaky zůstávají ve výchozím stavu.\n"
-"Příznaky začínající na 'no' slouží k zakázání možnosti."
+"Parametry generování mapy pro Generátor mapy - Fraktál.\n"
+"\"terén\" umožňuje generování \"nefraktálového\" terénu:\n"
+"oceány, ostrovy a podzemí."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5232,152 +5343,145 @@ msgid ""
 "to become shallower and occasionally dry.\n"
 "'altitude_dry': Reduces humidity with altitude."
 msgstr ""
+"Parametry generování mapy pro Generátor mapy - Údolí.\n"
+"„altitude_chill“: Snižuje teplotu s nadmořskou výškou.\n"
+"„humid_rivers“: Zvyšuje vlhkost podél řek.\n"
+"„vary_river_depth“: Pokud zapnuto, nízká vlhkost a vysoká teplota\n"
+"budou mít za následek mělčí nebo místy úplně vyschlé řeky.\n"
+"„altitude_dry“: Snižuje vlhkost s nadmořskou výškou."
 
 #: src/settings_translation_file.cpp
 msgid "Map generation attributes specific to Mapgen v5."
-msgstr ""
+msgstr "Parametry generování mapy pro Generátor mapy v5."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen v6.\n"
 "The 'snowbiomes' flag enables the new 5 biome system.\n"
 "When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n"
 "the 'jungles' flag is ignored."
 msgstr ""
-"Globální parametry generování mapy.\n"
-"V mapgenu v6 ovládal příznak 'decorations' všechny dekorace kromě\n"
-"stromů a tropické trávy. V ostatních mapgenech tento příznak řídí\n"
-"všechny dekorace.\n"
-"Neuvedené příznaky zůstávají ve výchozím stavu.\n"
-"Příznaky začínající na 'no' slouží k zakázání možnosti."
+"Parametry generování mapy pro Generátor mapy v6.\n"
+"Nastavení \"snowbiomes\" umožňuje systém 5 biomů.\n"
+"Pokud je nastavení \"snowbiomes\" zapnuto, džungle jsou automaticky\n"
+"zapnuty a nastavení \"jungles\" je ignorováno."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen v7.\n"
 "'ridges': Rivers.\n"
 "'floatlands': Floating land masses in the atmosphere.\n"
 "'caverns': Giant caves deep underground."
 msgstr ""
-"Globální parametry generování mapy.\n"
-"V mapgenu v6 ovládal příznak 'decorations' všechny dekorace kromě\n"
-"stromů a tropické trávy. V ostatních mapgenech tento příznak řídí\n"
-"všechny dekorace.\n"
-"Neuvedené příznaky zůstávají ve výchozím stavu.\n"
-"Příznaky začínající na 'no' slouží k zakázání možnosti."
+"Parametry generování mapy v Generátoru mapy v7.\n"
+"'hřebeny': Rivers.\n"
+"'létající ostrovy': Ostrovy vznášející se v prostoru.\n"
+"'jeskynní dutiny': Obrovské jeskyně hluboko v podzemí."
 
 #: src/settings_translation_file.cpp
 msgid "Map generation limit"
-msgstr ""
+msgstr "Limit generování mapy"
 
 #: src/settings_translation_file.cpp
 msgid "Map save interval"
 msgstr "Interval ukládání mapy"
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
-msgstr ""
+#, fuzzy
+msgid "Map shadows update frames"
+msgstr "Doba aktualizace mapy"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
-msgstr ""
+msgstr "Limit mapbloků"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock mesh generation delay"
-msgstr ""
+msgstr "Prodleva generování sítě mapbloků"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock mesh generator's MapBlock cache size in MB"
-msgstr ""
+msgstr "Velikost cache paměti v MB Generátoru mapy pro Mapbloky"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock unload timeout"
-msgstr ""
+msgstr "Časový limit pro vymazání Mapbloku z paměti"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Carpathian"
-msgstr "Mapgen plochy"
+msgstr "Generátor mapy - Carpathian"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen Carpathian specific flags"
-msgstr ""
+msgstr "Nastavení pro Generátor mapy - Carpathian"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Flat"
-msgstr "Mapgen plochy"
+msgstr "Generátor mapy - Plocha"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen Flat specific flags"
-msgstr ""
+msgstr "Nastavení Generátory mapy - Plocha"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Fractal"
-msgstr "Mapgen plochy"
+msgstr "Generátor mapy - Fraktál"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Fractal specific flags"
-msgstr "Mapgen údolí"
+msgstr "Nastavení pro Generátor mapy - Fraktál"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen V5"
-msgstr "Mapgen v5"
+msgstr "Generátor mapy V5"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen V5 specific flags"
-msgstr ""
+msgstr "Nastavení pro Generátor mapy v5"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen V6"
-msgstr "Mapgen v6"
+msgstr "Generátor mapy v6"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen V6 specific flags"
-msgstr ""
+msgstr "Nastavení pro Generátor mapy v6"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen V7"
-msgstr "Mapgen v7"
+msgstr "Generátor mapy v7"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen V7 specific flags"
-msgstr ""
+msgstr "Nastavení pro Generátor mapy v7"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen Valleys"
 msgstr "Mapgen údolí"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Valleys specific flags"
-msgstr "Mapgen údolí"
+msgstr "Nastavení pro Generátor mapy - Údolí"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen debug"
-msgstr "Ladění generátoru mapy"
+msgstr "Ladění Generátoru mapy"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen name"
-msgstr "Jméno generátoru mapy"
+msgstr "Jméno Generátoru mapy"
 
 #: src/settings_translation_file.cpp
 msgid "Max block generate distance"
-msgstr ""
+msgstr "Horní hranice vzdálenosti pro generování bloků"
 
 #: src/settings_translation_file.cpp
 msgid "Max block send distance"
-msgstr ""
+msgstr "Horní hranice vzdálenosti pro posílání bloků"
 
 #: src/settings_translation_file.cpp
 msgid "Max liquids processed per step."
-msgstr ""
+msgstr "Horní hranice počtu kapalin zpracovaných za jeden krok."
 
 #: src/settings_translation_file.cpp
 msgid "Max. clearobjects extra blocks"
@@ -5409,11 +5513,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum limit of random number of large caves per mapchunk."
-msgstr ""
+msgstr "Horní hranice pro náhodný počet velkých jeskyní na kus mapy."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum limit of random number of small caves per mapchunk."
-msgstr ""
+msgstr "Horní hranice pro náhodný počet malých jeskyní na kus mapy."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5558,11 +5662,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Minimum limit of random number of large caves per mapchunk."
-msgstr ""
+msgstr "Spodní hranice pro náhodný počet velkých jeskyní na kus mapy."
 
 #: src/settings_translation_file.cpp
 msgid "Minimum limit of random number of small caves per mapchunk."
-msgstr ""
+msgstr "Spodní hranice pro náhodný počet malých jeskyní na kus mapy."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -5578,7 +5682,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5589,6 +5693,11 @@ msgstr "Cesta k neproporcionálnímu písmu"
 msgid "Monospace font size"
 msgstr "Velikost neproporcionálního písma"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Velikost neproporcionálního písma"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5711,7 +5820,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5735,11 +5844,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5762,17 +5873,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5879,14 +5986,14 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Proportion of large caves that contain liquid."
-msgstr ""
+msgstr "Poměr velkých jeskyní s kapalinami."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6206,26 +6313,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6331,8 +6430,9 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
-msgstr ""
+#, fuzzy
+msgid "Show name tag backgrounds by default"
+msgstr "Tučné písmo jako výchozí"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6347,6 +6447,12 @@ msgid ""
 "Altering this value is for special usage, leaving it unchanged is\n"
 "recommended."
 msgstr ""
+"Velikost kusů mapy vytovřených Generátorem mapy v mapblocích (16 bloků).\n"
+"VAROVÁNÍ!: Hodnota vyšší než 5 nepřináší žádné zlepšení\n"
+"a zvyšuje riziko problémů.\n"
+"Snížení hodnoty zvýší husotou jeskyní a žalářů.\n"
+"Změna hodnoty je pro zvláštní případy, jinak je doporučeno\n"
+"nechat ji na výchozí hodnotě."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6369,11 +6475,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Small cave maximum number"
-msgstr ""
+msgstr "Horní hranice počtu malých jeskyní"
 
 #: src/settings_translation_file.cpp
 msgid "Small cave minimum number"
-msgstr ""
+msgstr "Spodní hranice počtu malých jeskyní"
 
 #: src/settings_translation_file.cpp
 msgid "Small-scale humidity variation for blending biomes on borders."
@@ -6438,6 +6544,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6550,7 +6664,7 @@ msgstr "Cesta k texturám"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6568,7 +6682,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6637,7 +6751,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6732,6 +6846,10 @@ msgstr "Zpoždění nápovědy"
 msgid "Touch screen threshold"
 msgstr "Práh šumu pláže"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6803,7 +6921,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6859,7 +6977,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Variation of number of caves."
-msgstr ""
+msgstr "Variace počtu jeskyní."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6995,6 +7113,11 @@ msgstr "Délka vodních vln"
 msgid "Waving plants"
 msgstr "Vlnění rostlin"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Barva obrysu bloku"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7016,7 +7139,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7024,14 +7147,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7124,13 +7240,13 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Y of upper limit of large caves."
-msgstr "Maximální počet emerge front"
+msgstr "Hodnota Y pro horní hranici velkých jeskyní."
 
 #: src/settings_translation_file.cpp
 msgid "Y-distance over which caverns expand to full size."
 msgstr ""
+"Vzdálenost Y, přes kterou se jeskynní dutiny rozšíří do plné velikosti."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7146,7 +7262,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of cavern upper limit."
-msgstr ""
+msgstr "Úroveň Y horní hranice jeskynních dutin."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of higher terrain that creates cliffs."
@@ -7160,24 +7276,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -7191,6 +7289,12 @@ msgstr "cURL timeout"
 msgid "cURL parallel limit"
 msgstr "cURL limit paralelních stahování"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kreativní mód: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Zranění: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7330,6 +7434,9 @@ msgstr "cURL limit paralelních stahování"
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "Neprůhlednost stínu písma (od 0 do 255)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Písma Freetype"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Bitová hloubka v celoobrazovkovém režimu"
 
@@ -7351,6 +7458,9 @@ msgstr "cURL limit paralelních stahování"
 #~ "Např.: 72 = 20 minut, 360 = 4 minuty, 1 = 24 hodin, 0 = čas zůstává stále "
 #~ "stejný."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instalace: soubor: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "Hloubka velké jeskyně"
@@ -7435,6 +7545,9 @@ msgstr "cURL limit paralelních stahování"
 #~ msgid "Strength of generated normalmaps."
 #~ msgstr "Síla vygenerovaných normálových map."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Pro zapnutí shaderů musíte používat OpenGL ovladač."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Plynulá kamera"
 
@@ -7447,5 +7560,8 @@ msgstr "cURL limit paralelních stahování"
 #~ msgid "Yes"
 #~ msgstr "Ano"
 
+#~ msgid "You died."
+#~ msgstr "Zemřel jsi."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index ff40ba138286a37a5e31da7ae394c3f4e80ed482..732d9f304da011b13fc462c158e1297da1315c89 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Danish (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2020-03-31 10:14+0000\n"
-"Last-Translator: sfan5 <sfan5@live.de>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-26 12:17+0000\n"
+"Last-Translator: Thomas Wagner Nielsen <thomas@viawords.com>\n"
 "Language-Team: Danish <https://hosted.weblate.org/projects/minetest/minetest/"
 "da/>\n"
 "Language: da\n"
@@ -12,7 +12,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
@@ -29,9 +29,8 @@ msgid "Exit to main menu"
 msgstr "Afslut til menu"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Lokal kommando"
+msgstr "Ugyldig kommando: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
@@ -43,9 +42,8 @@ msgid "List online players"
 msgstr "Enlig spiller"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Enlig spiller"
+msgstr "Online-spillere: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
@@ -63,20 +61,13 @@ msgstr "Genopstå"
 msgid "You died"
 msgstr "Du døde"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Du døde"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Lokal kommando"
+msgstr "Tilgængelige kommandoer:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Lokal kommando"
+msgstr "Tilgængelige kommandoer: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
@@ -99,6 +90,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 #, fuzzy
 msgid "An error occurred in a Lua script:"
@@ -189,9 +184,8 @@ msgid "Mod:"
 msgstr "Mod:"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No (optional) dependencies"
-msgstr "Valgfrie afhængigheder:"
+msgstr "Ingen (valgfrie) afhængigheder"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No game description provided."
@@ -310,6 +304,13 @@ msgstr "Installer"
 msgid "Install missing dependencies"
 msgstr "Valgfrie afhængigheder:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"Installer mod: Filtypen \"$1\" er enten ikke understøttet, ellers er arkivet "
+"korrupt"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -656,7 +657,8 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Persistens"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -767,16 +769,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Installer mod: Kunne ikke finde passende mappe navn for samling af mods $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Installer mod: Filtypen \"$1\" er enten ikke understøttet, ellers er arkivet "
-"korrupt"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Installer mod: Fil: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Kan ikke finde en korrekt mod eller samling af mods"
@@ -961,7 +953,7 @@ msgstr "Vær vært for spil"
 #: builtin/mainmenu/tab_online.lua
 #, fuzzy
 msgid "Address"
-msgstr "- Adresse: "
+msgstr "Adresse"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -1158,10 +1150,6 @@ msgstr "Glat belysning"
 msgid "Texturing:"
 msgstr "Teksturering:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "For at aktivere dybdeskabere skal OpenGL-driveren bruges."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Toneoversættelse"
@@ -1196,7 +1184,7 @@ msgstr "Bølgende blade"
 msgid "Waving Plants"
 msgstr "Bølgende planter"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Forbindelses fejl (tidsfristen udløb)."
 
@@ -1225,8 +1213,8 @@ msgid "Connection error (timed out?)"
 msgstr "Forbindelses fejl (udløbelse af tidsfrist?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Kunne ikke finde eller indlæse spil \""
+msgid "Could not find or load game"
+msgstr "Kunne ikke finde eller indlæse spillet: "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1269,14 +1257,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresse: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kreativ tilstand: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Skade: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Tilstand: "
@@ -1298,6 +1278,16 @@ msgstr "- Spiller mod spiller (PvP): "
 msgid "- Server Name: "
 msgstr "- Servernavn: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Der skete en fejl:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Automatic forward disabled"
@@ -1308,6 +1298,22 @@ msgstr "Fremadtast"
 msgid "Automatic forward enabled"
 msgstr "Fremadtast"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Camera update disabled"
@@ -1318,6 +1324,10 @@ msgstr "Tast til ændring af kameraopdatering"
 msgid "Camera update enabled"
 msgstr "Tast til ændring af kameraopdatering"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Skift kodeord"
@@ -1332,6 +1342,11 @@ msgstr "Tast for filmisk tilstand"
 msgid "Cinematic mode enabled"
 msgstr "Tast for filmisk tilstand"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Klient modding"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1340,6 +1355,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr "Forbinder til server..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Fortsæt"
@@ -1377,6 +1396,11 @@ msgstr ""
 "- Musehjul: vælge genstand\n"
 "- %s: snakke (chat)\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Opretter klient ..."
@@ -1593,6 +1617,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Lydniveau"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy, c-format
 msgid "Viewing range changed to %d"
@@ -1930,6 +1969,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Kunne ikke hente $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Kodeordene er ikke ens!"
@@ -2138,8 +2186,9 @@ msgid "Muted"
 msgstr "Lydløs"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Lydstyrke: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Lydstyrke: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2373,6 +2422,10 @@ msgstr ""
 "Justér DPI-konfigurationen til din skærm (ikke-X11 / kun Android) f.eks. til "
 "4k-skærme."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2659,6 +2712,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Ørkenstøjtærskel"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Snakkekommandoer"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2696,8 +2754,8 @@ msgid "Chat toggle key"
 msgstr "Tast for snak (chat)"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Snakkekommandoer"
+msgid "Chat weblinks"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2715,6 +2773,12 @@ msgstr "Tast for filmisk tilstand"
 msgid "Clean transparent textures"
 msgstr "Rene gennemsigtige teksturer"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klient"
@@ -2800,6 +2864,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Kommandotast"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Forbind glas"
@@ -2897,7 +2977,7 @@ msgstr "Crosshair alpha"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr "Crosshair alpha (uigennemsigtighed, mellem 0 og 255)."
 
 #: src/settings_translation_file.cpp
@@ -2977,8 +3057,8 @@ msgstr "Standard spil"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3106,6 +3186,10 @@ msgstr "Deaktiver antisnyd"
 msgid "Disallow empty passwords"
 msgstr "Tillad ikke tomme adgangskoder"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Domænenavn for server, til visning i serverlisten."
@@ -3155,7 +3239,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3186,13 +3277,6 @@ msgstr "Aktiver mod-sikkerhed"
 msgid "Enable players getting damage and dying."
 msgstr "Aktiver at spillere kan skades og dø."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Aktiver vilkårlig brugerinddata (kun til test)."
@@ -3292,6 +3376,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Udskrivningsinterval for motorprofileringsdata"
@@ -3501,11 +3591,15 @@ msgid "Font size"
 msgstr "Skriftstørrelse"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3514,6 +3608,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3582,11 +3687,6 @@ msgstr "Fraktaltype"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid "FreeType fonts"
-msgstr "Freetype-skrifttyper"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3640,7 +3740,7 @@ msgstr "Globale tilbagekald"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Globale kortoprettelsesattributter.\n"
 "I Mapgen v6 kontrollerer flaget »decorations« alle dekorationer undtagen "
@@ -4131,7 +4231,8 @@ msgstr ""
 "Er normalt kun krævet af kerne/indbygningsbidragydere"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Udstyr chatkommandoer ved registrering."
 
 #: src/settings_translation_file.cpp
@@ -4221,7 +4322,7 @@ msgid "Joystick button repetition interval"
 msgstr "Joystick-knaps gentagelsesinterval"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5386,7 +5487,7 @@ msgstr "Interval for kortlagring"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "Væskeopdateringsudløsning"
 
 #: src/settings_translation_file.cpp
@@ -5696,7 +5797,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5707,6 +5808,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5830,7 +5935,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5854,11 +5959,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5881,17 +5988,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5999,9 +6102,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6326,26 +6429,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6456,7 +6551,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6563,6 +6658,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6678,7 +6781,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6696,7 +6799,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6766,7 +6869,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6861,6 +6964,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr "Strandstøjtærskel"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6932,7 +7039,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7125,6 +7232,10 @@ msgstr "Bølgende vand"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7146,7 +7257,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7154,14 +7265,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7290,24 +7394,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -7321,6 +7407,12 @@ msgstr "cURL-tidsudløb"
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kreativ tilstand: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Skade: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7449,6 +7541,10 @@ msgstr ""
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "Alfa for skrifttypeskygge (uigennemsigtighed, mellem 0 og 255)."
 
+#, fuzzy
+#~ msgid "FreeType fonts"
+#~ msgstr "Freetype-skrifttyper"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Fuldskærm BPP"
 
@@ -7468,6 +7564,9 @@ msgstr ""
 #~ msgid "IPv6 support."
 #~ msgstr "Understøttelse af IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Installer mod: Fil: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "Dybde for stor hule"
@@ -7532,11 +7631,18 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Enlig spiller"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "For at aktivere dybdeskabere skal OpenGL-driveren bruges."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Aktiver filmisk"
 
 #~ msgid "Yes"
 #~ msgstr "Ja"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Du døde"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index b8362beb26ea5a3fdef3752739838ca9b079e1c0..972359a3255e4acbe473beda007b4830894ad446 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: German (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-03-02 15:50+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-29 21:28+0000\n"
 "Last-Translator: Wuzzy <almikes@aol.com>\n"
 "Language-Team: German <https://hosted.weblate.org/projects/minetest/minetest/"
 "de/>\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Maximale Größe der ausgehenden Chatwarteschlange"
+msgstr "Die ausgehende Chatwarteschlange leeren"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Chatbefehle"
+msgstr "Leerer Befehl."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Hauptmenü"
+msgstr "Zum Hauptmenü verlassen"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Lokaler Befehl"
+msgstr "Ungültiger Befehl: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Befehl erteilt: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Einzelspieler"
+msgstr "Online spielende Spieler auflisten"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Einzelspieler"
+msgstr "Online-Spieler: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Die ausgehende Chatwarteschlange ist nun leer."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Dieser Befehl ist vom Server deaktiviert."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,41 @@ msgstr "Wiederbeleben"
 msgid "You died"
 msgstr "Sie sind gestorben"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Sie sind gestorben"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Lokaler Befehl"
+msgstr "Verfügbare Befehle:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Lokaler Befehl"
+msgstr "Verfügbare Befehle: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Befehl nicht verfügbar: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Hilfe für Befehle erhalten"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"„.help <Befehl>“ benutzen, um mehr Informationen zu erhalten, oder „.help "
+"all“ benutzen, um alles aufzulisten."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <Befehl>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<keine verfügbar>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "In einem Lua-Skript ist ein Fehler aufgetreten:"
@@ -303,6 +296,10 @@ msgstr "$1 installieren"
 msgid "Install missing dependencies"
 msgstr "Fehlende Abhängigkeiten installieren"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Installation: Nicht unterstützter Dateityp oder kaputtes Archiv"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -346,7 +343,7 @@ msgstr "Deinstallieren"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update"
-msgstr "Aktualisieren"
+msgstr "Update"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
@@ -564,7 +561,7 @@ msgstr "Sind Sie sicher, dass „$1“ gelöscht werden soll?"
 #: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua
 #: src/client/keycode.cpp
 msgid "Delete"
-msgstr "Entfernen"
+msgstr "Löschen"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: failed to delete \"$1\""
@@ -635,7 +632,7 @@ msgid "Offset"
 msgstr "Versatz"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Persistenz"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -747,15 +744,6 @@ msgstr ""
 "Modinstallation: Geeigneter Verzeichnisname für Modpack $1 konnte nicht "
 "gefunden werden"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Installation: Nicht unterstützter Dateityp „$1“ oder fehlerhaftes Archiv"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Installation: Datei: „$1“"
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Keine gültige Mod oder Modpack gefunden"
@@ -792,16 +780,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Über"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Aktive Mitwirkende"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Reichweite aktiver Objekte"
+msgstr "Aktiver Renderer:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -936,9 +923,8 @@ msgid "Start Game"
 msgstr "Spiel starten"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adresse: "
+msgstr "Adresse"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -954,22 +940,20 @@ msgstr "Kreativmodus"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Schaden"
+msgstr "Schaden / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Favorit löschen"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favorit"
+msgstr "Favoriten"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Inkompatible Server"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -980,16 +964,14 @@ msgid "Ping"
 msgstr "Latenz"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Server veröffentlichen"
+msgstr "Öffentliche Server"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Neu laden"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Serverbeschreibung"
 
@@ -1034,13 +1016,12 @@ msgid "Connected Glass"
 msgstr "Verbundenes Glas"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Schriftschatten"
+msgstr "Dynamische Schatten"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dynamische Schatten: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1048,15 +1029,15 @@ msgstr "Schöne Blätter"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Hoch"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Niedrig"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Mittel"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1084,7 +1065,7 @@ msgstr "Blöcke umranden"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "None"
-msgstr "Keines"
+msgstr "Keine"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Leaves"
@@ -1130,10 +1111,6 @@ msgstr "Weiches Licht"
 msgid "Texturing:"
 msgstr "Texturierung:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Um Shader zu aktivieren, muss der OpenGL-Treiber genutzt werden."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Dynamikkompression"
@@ -1148,11 +1125,11 @@ msgstr "Trilinearer Filter"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Sehr hoch"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Sehr niedrig"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1166,7 +1143,7 @@ msgstr "Flüssigkeitswellen"
 msgid "Waving Plants"
 msgstr "Wehende Pflanzen"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Verbindungsfehler, Zeitüberschreitung."
 
@@ -1176,7 +1153,7 @@ msgstr "Fertig!"
 
 #: src/client/client.cpp
 msgid "Initializing nodes"
-msgstr "Initialisiere Blöcke"
+msgstr "Blöcke initialisieren"
 
 #: src/client/client.cpp
 msgid "Initializing nodes..."
@@ -1188,15 +1165,15 @@ msgstr "Lade Texturen …"
 
 #: src/client/client.cpp
 msgid "Rebuilding shaders..."
-msgstr "Shader wiederherstellen …"
+msgstr "Shader erneuern…"
 
 #: src/client/clientlauncher.cpp
 msgid "Connection error (timed out?)"
 msgstr "Verbindungsfehler (Zeitüberschreitung?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Spiel konnte nicht gefunden oder geladen werden: \""
+msgid "Could not find or load game"
+msgstr "Spiel konnte nicht gefunden oder geladen werden: "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1238,14 +1215,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresse: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kreativmodus: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Schaden: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Modus: "
@@ -1267,6 +1236,15 @@ msgstr "- Spielerkampf: "
 msgid "- Server Name: "
 msgstr "- Servername: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Ein Serialisierungsfehler ist aufgetreten:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Zugriff verweigert. Grund: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Vorwärtsautomatik deaktiviert"
@@ -1275,6 +1253,22 @@ msgstr "Vorwärtsautomatik deaktiviert"
 msgid "Automatic forward enabled"
 msgstr "Vorwärtsautomatik aktiviert"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Blockgrenzen verborgen"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Blockgrenzen für alle Blöcke angezeigt"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Blockgrenzen für aktuellen Block angezeigt"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Blockgrenzen für Blöcke in Nähe angezeigt"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kameraaktualisierung deaktiviert"
@@ -1283,6 +1277,11 @@ msgstr "Kameraaktualisierung deaktiviert"
 msgid "Camera update enabled"
 msgstr "Kameraaktualisierung aktiviert"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+"Blockgrenzen können nicht gezeigt werden („basic_debug“-Privileg benötigt)"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Passwort ändern"
@@ -1295,13 +1294,21 @@ msgstr "Filmmodus deaktiviert"
 msgid "Cinematic mode enabled"
 msgstr "Filmmodus aktiviert"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Client getrennt"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Clientseitige Skripte sind deaktiviert"
 
 #: src/client/game.cpp
 msgid "Connecting to server..."
-msgstr "Verbinde mit Server …"
+msgstr "Mit Server verbinden …"
+
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Verbindung aus unbekanntem Grund fehlgeschlagen"
 
 #: src/client/game.cpp
 msgid "Continue"
@@ -1340,6 +1347,11 @@ msgstr ""
 "- Mausrad: Gegenstand wählen\n"
 "- %s: Chat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Adresse konnte nicht aufgelöst werden: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Client erstellen …"
@@ -1414,7 +1426,7 @@ msgstr "Schnellmodus aktiviert"
 
 #: src/client/game.cpp
 msgid "Fast mode enabled (note: no 'fast' privilege)"
-msgstr "Schnellmodus aktiviert (Achtung: Kein „fast“-Privileg)"
+msgstr "Schnellmodus aktiviert (Hinweis: Kein „fast“-Privileg)"
 
 #: src/client/game.cpp
 msgid "Fly mode disabled"
@@ -1426,7 +1438,7 @@ msgstr "Flugmodus aktiviert"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled (note: no 'fly' privilege)"
-msgstr "Flugmodus aktiviert (Achtung: Kein „fly“-Privileg)"
+msgstr "Flugmodus aktiviert (Hinweis: Kein „fly“-Privileg)"
 
 #: src/client/game.cpp
 msgid "Fog disabled"
@@ -1469,9 +1481,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Übersichtskarte momentan von Spiel oder Mod deaktiviert"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Einzelspieler"
+msgstr "Mehrspieler"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1483,7 +1494,7 @@ msgstr "Geistmodus aktiviert"
 
 #: src/client/game.cpp
 msgid "Noclip mode enabled (note: no 'noclip' privilege)"
-msgstr "Geistmodus aktiviert (Achtung: Kein „noclip“-Privileg)"
+msgstr "Geistmodus aktiviert (Hinweis: Kein „noclip“-Privileg)"
 
 #: src/client/game.cpp
 msgid "Node definitions..."
@@ -1545,6 +1556,22 @@ msgstr "Tonsystem ist in diesem Build nicht unterstützt"
 msgid "Sound unmuted"
 msgstr "Ton nicht mehr stumm"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Auf dem Server läuft möglicherweise eine andere Version von %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+"Verbindung konnte nicht zu %s aufgebaut werden, weil IPv6 deaktiviert ist"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Konnte nicht auf %s lauschen, weil IPv6 deaktiviert ist"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1879,6 +1906,14 @@ msgstr "Übersichtskarte im Bodenmodus, Zoom ×%d"
 msgid "Minimap in texture mode"
 msgstr "Übersichtskarte im Texturmodus"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Fehler beim Öffnen der Webseite"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Webseite öffnen"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Passwörter stimmen nicht überein!"
@@ -1909,9 +1944,8 @@ msgid "Proceed"
 msgstr "Fortsetzen"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "„Spezial“ = runter"
+msgstr "„Aux1“ = runter"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1923,7 +1957,7 @@ msgstr "Auto-Springen"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1931,7 +1965,7 @@ msgstr "Rückwärts"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Blockgrenzen"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2084,8 +2118,9 @@ msgid "Muted"
 msgstr "Stumm"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Tonlautstärke: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Tonlautstärke: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2110,15 +2145,14 @@ msgstr ""
 "zentriert."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Den virtuellen Joystick benutzen, um die „Aux“-Taste zu "
+"(Android) Den virtuellen Joystick benutzen, um die „Aux1“-Taste zu "
 "betätigen.\n"
-"Falls aktiviert, wird der virtuelle Joystick außerdem die „Aux“-Taste "
+"Falls aktiviert, wird der virtuelle Joystick außerdem die „Aux1“-Taste "
 "drücken, wenn er sich außerhalb des Hauptkreises befindet."
 
 #: src/settings_translation_file.cpp
@@ -2354,6 +2388,12 @@ msgid ""
 "screens."
 msgstr "DPI des Bildschirms (nicht für X11/Android) z.B. für 4K-Bildschirme."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Die erfasste Anzeigendichte anpassen, benutzt für die Skalierung von UI-"
+"Elementen."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2493,14 +2533,12 @@ msgid "Autoscaling mode"
 msgstr "Autoskalierungsmodus"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Sprungtaste"
+msgstr "Aux1-Taste"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Spezialtaste zum Klettern/Sinken"
+msgstr "Aux1-Taste zum Klettern/Sinken"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2653,9 +2691,12 @@ msgstr ""
 "Wobei 0.0 die minimale Lichtstufe und 1.0 die höchste Lichtstufe ist."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Chatnachrichten-Kick-Schwellwert"
+msgstr "Chatbefehlzeitnachrichtenschwellwert"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Chatbefehle"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2690,8 +2731,8 @@ msgid "Chat toggle key"
 msgstr "Taste zum Umschalten des Chatprotokolls"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Chatbefehle"
+msgid "Chat weblinks"
+msgstr "Chatweblinks"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2709,6 +2750,14 @@ msgstr "Filmmodustaste"
 msgid "Clean transparent textures"
 msgstr "Transparente Texturen säubern"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Anklickbare Weblinks (Mittelklick oder Strg+Linksklick) werden in der "
+"Chatkonsolenausgabe aktiviert."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Client"
@@ -2754,9 +2803,8 @@ msgid "Colored fog"
 msgstr "Gefärbter Nebel"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Gefärbter Nebel"
+msgstr "Gefärbte Schatten"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2801,6 +2849,31 @@ msgstr ""
 msgid "Command key"
 msgstr "Befehlstaste"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Zu verwendendes Kompressionsniveau, wenn Kartenblöcke auf den Datenträger "
+"gespeichert werden.\n"
+"-1 - Standard-Kompressionsniveau benutzen\n"
+"0 - geringste Kompression, am schnellsten\n"
+"9 - beste Kompression, am langsamsten"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Kompressionsniveau für Kartenblöcke, die zu Clients gesendet werden.\n"
+"-1 - Standard-Kompressionsniveau benutzen\n"
+"0 - keine Kompression, am schnellsten\n"
+"9 - beste Kompression, am langsamsten"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Verbundenes Glas"
@@ -2902,10 +2975,10 @@ msgstr "Fadenkreuzundurchsichtigkeit"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
-"Fadenkreuzundurchsichtigkeit (Wert zwischen 0 und 255).\n"
-"Gilt auch für das Objektfadenkreuz"
+"Fadenkreuz-Alpha (Undurchsichtigkeit, zwischen 0 und 255).\n"
+"Gilt auch für das Objektfadenkreuz."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2987,10 +3060,14 @@ msgstr "Standardstapelgröße"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Definiert die Schattenfilterqualität.\n"
+"Dies simuliert den weichen Schatteneffekt, indem eine PCF- oder Poisson-"
+"Scheibe angewendet wird,\n"
+"aber dies verbraucht auch mehr Ressourcen."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3119,6 +3196,10 @@ msgstr "Anti-Cheat deaktivieren"
 msgid "Disallow empty passwords"
 msgstr "Leere Passwörter verbieten"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Anzeigendichtenskalierungsfaktor"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Domainname des Servers. Wird in der Serverliste angezeigt."
@@ -3169,9 +3250,22 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Aktiviert eine Poisson-Scheibenfilterung.\n"
+"Falls aktiv, werden Poisson-Scheiben verwendet, um „weiche Schatten“ zu "
+"erzeugen. Ansonsten wird die PCF-Filterung benutzt."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Aktiviert gefärbte Schatten. \n"
+"Falls aktiv, werden transluzente Blöcke gefärbte Schatten werfen. Dies ist "
+"rechenintensiv."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3197,13 +3291,6 @@ msgstr "Modsicherheit aktivieren"
 msgid "Enable players getting damage and dying."
 msgstr "Spielerschaden und -tod aktivieren."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Schaltet zufällige Steuerung ein (nur zum Testen verwendet)."
@@ -3324,6 +3411,16 @@ msgstr ""
 "die Tonsteuerung im Spiel wird funktionslos sein.\n"
 "Die Änderung dieser Einstellung benötigt einen Neustart."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+"Aktiviert Kompromisse, die die CPU-Last verringern oder die Rendering-"
+"Leistung erhöhen\n"
+"auf Kosten kleinerer visueller Fehler, die die Spielbarkeit nicht "
+"beeinträchtigen."
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Engine-Profiling-Datenausgabeintervall"
@@ -3388,12 +3485,11 @@ msgid "Fast movement"
 msgstr "Schnell bewegen"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Schnelle Bewegung (mit der „Spezial“-Taste).\n"
+"Schnelle Bewegung (mit der „Aux1“-Taste).\n"
 "Dazu wird das „fast“-Privileg auf dem Server benötigt."
 
 #: src/settings_translation_file.cpp
@@ -3426,18 +3522,18 @@ msgid "Filmic tone mapping"
 msgstr "Filmische Dynamikkompression"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
 "light edges to transparent textures. Apply a filter to clean that up\n"
 "at texture load time. This is automatically enabled if mipmapping is enabled."
 msgstr ""
-"Gefilterte Texturen können RGB-Werte mit 100% transparenten Nachbarn,\n"
+"Gefilterte Texturen können RGB-Werte mit voll transparenten Nachbarn,\n"
 "die PNG-Optimierer üblicherweise verwerfen, mischen. Manchmal\n"
 "resultiert dies in einer dunklen oder hellen Kante bei transparenten\n"
-"Texturen. Aktivieren Sie diesen Filter, um dies beim Laden der\n"
-"Texturen aufzuräumen."
+"Texturen. Aktivieren Sie einen Filter, um dies beim Laden der\n"
+"Texturen aufzuräumen. Dies wird automatisch aktiviert, falls Mipmapping "
+"aktiviert ist."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3530,12 +3626,17 @@ msgid "Font size"
 msgstr "Schriftgröße"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
-msgstr "Schriftgröße der Standardschrift in Punkt (pt)."
+msgid "Font size divisible by"
+msgstr "Schriftgröße teilbar durch"
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Schriftgröße der Standardschrift, wobei 1 Einheit = 1 Pixel bei 96 DPI"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr "Schriftgröße der Festbreitenschrift in Punkt (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+"Schriftgröße der Festbreitenschrift, wobei 1 Einheit = 1 Pixel bei 96 DPI"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3546,6 +3647,26 @@ msgstr ""
 "der Chateingabe in Punkt (pt).\n"
 "Der Wert 0 wird die Standardschriftgröße benutzen."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+"Bei Schriften im Pixelstil, die sich nicht gut skalieren lassen, stellt dies "
+"sicher,\n"
+"dass die mit dieser Schrift verwendeten Schriftgrößen immer durch diesen "
+"Wert\n"
+"in Pixeln teilbar ist. Zum Beispiel: Eine Pixelschrift mit einer Höhe von 16 "
+"Pixeln\n"
+"sollte auf 16 gesetzt werden, so dass sie immer nur die Größe 16, 32, 48 "
+"usw. hat,\n"
+"damit eine Mod, die eine Größe von 25 anfordert, 32 erhält."
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3616,10 +3737,6 @@ msgstr ""
 "Anteil der sichtbaren Entfernung, in welcher begonnen wird, den Nebel zu "
 "rendern"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "FreeType-Schriften"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3681,7 +3798,7 @@ msgstr "Globale Rückruffunktionen"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Globale Kartengenerierungsattribute.\n"
 "Im Kartengenerator v6 wird das „decorations“-Flag alle Dekorationen außer\n"
@@ -3771,10 +3888,10 @@ msgid "Heat noise"
 msgstr "Hitzenrauschen"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Höhenkomponente der anfänglichen Fenstergröße."
+msgstr ""
+"Höhenkomponente der anfänglichen Fenstergröße. Im Vollbildmodus ignoriert."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -4029,12 +4146,11 @@ msgstr ""
 "unnötig zu belasten."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Falls deaktiviert, wird die „Spezial“-Taste benutzt, um schnell zu fliegen,\n"
+"Falls deaktiviert, wird die „Aux1“-Taste benutzt, um schnell zu fliegen,\n"
 "wenn sowohl Flug- als auch Schnellmodus aktiviert sind."
 
 #: src/settings_translation_file.cpp
@@ -4063,13 +4179,12 @@ msgstr ""
 "Dafür wird das „noclip“-Privileg auf dem Server benötigt."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Falls aktiviert, wird die „Spezial“-Taste statt der „Schleichen“-Taste zum\n"
+"Falls aktiviert, wird die „Aux1“-Taste statt der „Schleichen“-Taste zum\n"
 "Herunterklettern und Sinken benutzt."
 
 #: src/settings_translation_file.cpp
@@ -4134,6 +4249,9 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Falls die Ausführung eines Chatbefehls länger als diese angegebene Zeit in\n"
+"Sekunden braucht, wird die Zeitinformation an die Chatbefehlsnachricht "
+"angehängt"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4196,7 +4314,7 @@ msgstr ""
 "Dies wird normalerweise nur von Haupt-/builtin-Entwicklern benötigt"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr "Chatbefehle bei ihrer Registrierung instrumentieren."
 
 #: src/settings_translation_file.cpp
@@ -4292,7 +4410,7 @@ msgid "Joystick button repetition interval"
 msgstr "Joystick-Button-Wiederholungsrate"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Joystick-Totbereich"
 
 #: src/settings_translation_file.cpp
@@ -5412,9 +5530,8 @@ msgid "Map save interval"
 msgstr "Speicherintervall der Karte"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Flüssigkeitsaktualisierungstakt"
+msgid "Map shadows update frames"
+msgstr "Kartenschatten-Aktualisierungsframes"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5528,7 +5645,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Maximale Distanz zum Rendern von Schatten."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5666,19 +5783,20 @@ msgstr ""
 "zu begrenzen."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Maximale Zeit in ms, die das Herunterladen einer Datei (z.B. einer Mod) "
-"dauern darf."
+"Maximale Zeit in Millisekunden, die das Herunterladen einer Datei (z.B. "
+"einer Mod) dauern darf."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Maximale Zeit in Millisekunden, die eine interaktive Anfrage (z.B. "
+"Serverlistenanfrage) brauchen darf."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5744,8 +5862,8 @@ msgid "Mod channels"
 msgstr "Mod-Kanäle"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "Modifiziert die Größe der HUD-Leistenelemente."
+msgid "Modifies the size of the HUD elements."
+msgstr "Modifiziert die Größe der HUD-Elemente."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
@@ -5755,6 +5873,10 @@ msgstr "Pfad der Festbreitenschrift"
 msgid "Monospace font size"
 msgstr "Größe der Festbreitenschrift"
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr "Festbreitenschriftgröße teilbar durch"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Berghöhenrauschen"
@@ -5903,7 +6025,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Anzahl der zusätzlichen Kartenblöcke, welche mit /clearobjects gleichzeitig\n"
@@ -5934,19 +6056,17 @@ msgstr ""
 "Das Pausemenü öffnen, wenn der Fokus des Fensters verloren geht.\n"
 "Wird nicht pausieren, wenn ein Formspec geöffnet ist."
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Optionaler manueller Wert für die Farbe von Chat-Weblinks."
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
-"Pfad der Ersatzschrift.\n"
-"Falls die „freetype“-Einstellung aktiviert ist: Muss eine TrueType-Schrift "
-"sein.\n"
-"Falls die „freetype“-Einstellung deaktiviert ist: Muss eine Bitmap- oder XML-"
-"Vektor-Schrift sein.\n"
+"Pfad der Ersatzschrift. Muss eine TrueType-Schrift sein.\n"
 "Diese Schrift wird für bestimmte Sprachen benutzt, oder, wenn die "
 "Standardschrift nicht verfügbar ist."
 
@@ -5974,31 +6094,19 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
-"Pfad der Standardschrift.\n"
-"Falls die „freetype“-Einstellung aktiviert ist: Muss eine TrueType-Schrift "
-"sein.\n"
-"Falls die „freetype“-Einstellung deaktiviert ist: Muss eine Bitmap- oder XML-"
-"Vektor-Schrift sein.\n"
+"Pfad der Standardschrift. Muss eine TrueType-Schrift sein.\n"
 "Die Ersatzschrift wird benutzt, falls diese Schrift nicht geladen werden "
 "kann."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
-"Pfad der Festbreitenschrift.\n"
-"Falls die „freetype“-Einstellung aktiviert ist: Muss eine TrueType-Schrift "
-"sein.\n"
-"Falls die „freetype“-Einstellung deaktiviert ist: Muss eine Bitmap- oder XML-"
-"Vektor-Schrift sein.\n"
+"Pfad der Festbreitenschrift. Muss eine TrueType-Schrift sein.\n"
 "Diese Schrift wird z.B. für die Konsole und die Profiler-Anzeige benutzt."
 
 #: src/settings_translation_file.cpp
@@ -6054,9 +6162,8 @@ msgid "Player versus player"
 msgstr "Spielerkampf"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Bilinearer Filter"
+msgstr "Poissonfilter"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6113,9 +6220,9 @@ msgstr "Prometheus-Lauschadresse"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Prometheus-Lauschadresse.\n"
 "Falls Minetest mit der ENABLE_PROMETEUS-Option kompiliert wurde,\n"
@@ -6461,36 +6568,37 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Setzt die Schattenstärke.\n"
+"Ein niedrigerer Wert führt zu schwächeren Schatten, ein höherer Wert führt "
+"zu dunkleren Schatten."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Setzt den Radius von weichen Schatten.\n"
+"Niedrigere Werte führen zu schärferen Schatten, größere Werte führen zu "
+"weicheren Schatten.\n"
+"Minimalwert: 1.0; Maximalwert: 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Setzt die Neigung vom Sonnen-/Mondorbit in Grad.\n"
+"0 = keine Neigung / vertikaler Orbit.\n"
+"Minimalwert: 0.0; Maximalwert: 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Auf „wahr“ setzen, um wehende Blätter zu aktivieren.\n"
+"Auf „wahr“ setzen, um Shadow-Mapping zu aktivieren.\n"
 "Dafür müssen Shader aktiviert sein."
 
 #: src/settings_translation_file.cpp
@@ -6523,6 +6631,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Setzt die Schattentexturqualität auf 32 Bits.\n"
+"Falls aktiviert, werden 16-Bit-Texturen benutzt.\n"
+"Dies kann zu viel mehr Artefakten im Schatten führen."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6541,22 +6652,20 @@ msgstr ""
 "Das funktioniert nur mit dem OpenGL-Grafik-Backend."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Bildschirmfotoqualität"
+msgstr "Schattenfilterqualität"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Maximale Schattenrenderdistanz von Schattenkarten in Blöcken"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Schattenkartentextur in 32 Bits"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Minimale Texturengröße"
+msgstr "Schattenkartentexturengröße"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6568,7 +6677,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Schattenstärke"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6591,8 +6700,8 @@ msgstr ""
 "Nach Änderung ist ein Neustart erforderlich."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
-msgstr "Namensschildhintergründe standardmäßig anzeigen"
+msgid "Show name tag backgrounds by default"
+msgstr "Standardmäßig Hintergründe für Namensschilder anzeigen"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6629,7 +6738,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Himmelskörperorbitneigung"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6690,9 +6799,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Schleichgeschwindigkeit, in Blöcken pro Sekunde."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Schriftschatten-Undurchsichtigkeit"
+msgstr "Weicher-Schatten-Radius"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6723,6 +6831,19 @@ msgstr ""
 "bestimmte\n"
 "(oder alle) Gegenstände setzen kann."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Eine vollständige Aktualisierung der Schattenkarte über der angegebenen\n"
+"Anzahl Frames ausbreiten. Höhere Werte können dazu führen, dass\n"
+"Schatten langsamer reagieren,\n"
+"niedrigere Werte sind rechenintensiver.\n"
+"Minimalwert: 1; Maximalwert: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6857,8 +6978,11 @@ msgstr "Texturenpfad"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Texturengröße zum Rendern der Schattenkarte.\n"
+"Dies muss eine Zweierpotenz sein.\n"
+"Größere Werte erzeugen bessere Schatten, aber dies ist auch rechenintensiver."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6884,7 +7008,7 @@ msgid "The URL for the content repository"
 msgstr "Die URL für den Inhaltespeicher"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "Der Totbereich des Joysticks"
 
 #: src/settings_translation_file.cpp
@@ -6961,7 +7085,6 @@ msgstr ""
 "konfiguriert werden."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6970,7 +7093,7 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Das Renderer-Backend für Irrlicht.\n"
+"Das Renderer-Backend.\n"
 "Ein Neustart ist erforderlich, wenn dies geändert wird.\n"
 "Anmerkung: Auf Android belassen Sie dies bei OGLES1, wenn Sie sich unsicher "
 "sind.\n"
@@ -6982,7 +7105,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Die Empfindlichkeit der Joystick-Achsen, um den\n"
 "Pyramidenstumpf der Spielansicht herumzubewegen."
@@ -7109,6 +7232,10 @@ msgstr "Tooltip-Verzögerung"
 msgid "Touch screen threshold"
 msgstr "Touchscreenschwellwert"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "Kompromisse für Performanz"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Bäumerauschen"
@@ -7192,7 +7319,7 @@ msgstr "Bilineare Filterung bei der Skalierung von Texturen benutzen."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7324,9 +7451,8 @@ msgid "Viewing range"
 msgstr "Sichtweite"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Virtueller Joystick löst Aux-Taste aus"
+msgstr "Virtueller Joystick löst Aux1-Taste aus"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7404,6 +7530,10 @@ msgstr "Flüssigkeitswellen: Wellenlänge"
 msgid "Waving plants"
 msgstr "Wehende Pflanzen"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Weblinkfarbe"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7430,13 +7560,12 @@ msgstr ""
 "korrekt unterstützen."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7447,27 +7576,14 @@ msgstr ""
 "die\n"
 "minimale Texturengröße für die vergrößerten Texturen; höhere Werte führen\n"
 "zu einem schärferen Aussehen, aber erfordern mehr Speicher. Zweierpotenzen\n"
-"werden empfohlen. Ein Wert größer als 1 könnte keinen sichtbaren Effekt\n"
-"hervorbringen, es sei denn, der bilineare, trilineare oder anisotropische "
-"Filter\n"
-"ist aktiviert.\n"
+"werden empfohlen. Diese Einstellung trifft NUR dann in Kraft, falls\n"
+"der bilineare/trilineare/anisotrope Filter aktiviert ist.\n"
 "Dies wird außerdem verwendet als die Basisblocktexturengröße für\n"
 "welt-ausgerichtete automatische Texturenskalierung."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Ob FreeType-Schriften benutzt werden. Dafür muss FreeType-Unterstüzung "
-"einkompiliert worden sein.\n"
-"Falls deaktiviert, werden stattdessen Bitmap- und XML-Vektor-Schriften "
-"benutzt."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 "Ob Namensschildhintergründe standardmäßig angezeigt werden sollen.\n"
@@ -7526,9 +7642,9 @@ msgstr ""
 "Drücken von F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Breiten-Komponente der anfänglichen Fenstergröße."
+msgstr ""
+"Breiten-Komponente der anfänglichen Fenstergröße. Im Vollbildmodus ignoriert."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7632,49 +7748,24 @@ msgstr "Y-Höhe von niedrigerem Gelände und dem Meeresgrund."
 msgid "Y-level of seabed."
 msgstr "Y-Höhe vom Meeresgrund."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"ZLib-Kompressionsniveau für Kartenblöcke im Festspeicher.\n"
-"-1 - Zlib-Standard-Kompressionsniveau\n"
-"0 - keine Kompression, am schnellsten\n"
-"9 - beste Kompression, am langsamsten\n"
-"(Niveaus 1-3 verwenden Zlibs „schnelles“ Verfahren, 4-9 das normale "
-"Verfahren)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"ZLib-Kompressionsniveau für Kartenblöcke, die zu Clients gesendet werden.\n"
-"-1 - Zlib-Standard-Kompressionsniveau\n"
-"0 - keine Kompression, am schnellsten\n"
-"9 - beste Kompression, am langsamsten\n"
-"(Niveaus 1-3 verwenden Zlibs „schnelles“ Verfahren, 4-9 das normale "
-"Verfahren)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL-Dateidownload-Zeitüberschreitung"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL-Zeitüberschreitung"
+msgstr "cURL-Interaktiv-Zeitüberschreitung"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "cURL-Parallel-Begrenzung"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kreativmodus: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Schaden: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7860,6 +7951,9 @@ msgstr "cURL-Parallel-Begrenzung"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Schriftgröße der Ersatzschrift in Punkt (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType-Schriften"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Vollbildfarbtiefe"
 
@@ -7878,6 +7972,9 @@ msgstr "cURL-Parallel-Begrenzung"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6-Unterstützung."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Installation: Datei: „$1“"
+
 #~ msgid "Lava depth"
 #~ msgstr "Lavatiefe"
 
@@ -7985,6 +8082,18 @@ msgstr "cURL-Parallel-Begrenzung"
 #~ msgid "Select Package File:"
 #~ msgstr "Paket-Datei auswählen:"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "Setzt die Schattenupdatezeit.\n"
+#~ "Ein niedrigerer Wert bedeutet, dass Schatten und die Karte schneller "
+#~ "aktualisiert werden, aber dies verbraucht mehr Ressourcen.\n"
+#~ "Minimalwert: 0.001 Sekunden. Maximalwert: 0.2 Sekunden.\n"
+#~ "(Beachten Sie die englische Notation mit Punkt als Dezimaltrennzeichen.)"
+
 #~ msgid "Shadow limit"
 #~ msgstr "Schattenbegrenzung"
 
@@ -8013,6 +8122,9 @@ msgstr "cURL-Parallel-Begrenzung"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Diese Schrift wird von bestimmten Sprachen benutzt."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Um Shader zu aktivieren, muss der OpenGL-Treiber genutzt werden."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Filmmodus umschalten"
 
@@ -8036,6 +8148,16 @@ msgstr "cURL-Parallel-Begrenzung"
 #~ msgid "Waving water"
 #~ msgstr "Wasserwellen"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Ob FreeType-Schriften benutzt werden. Dafür muss FreeType-Unterstüzung "
+#~ "einkompiliert worden sein.\n"
+#~ "Falls deaktiviert, werden stattdessen Bitmap- und XML-Vektor-Schriften "
+#~ "benutzt."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Ob Verliese manchmal aus dem Gelände herausragen."
 
@@ -8053,5 +8175,8 @@ msgstr "cURL-Parallel-Begrenzung"
 #~ msgid "Yes"
 #~ msgstr "Ja"
 
+#~ msgid "You died."
+#~ msgstr "Sie sind gestorben."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index ffddc1a132a4b3276e94d7a7829871803284bed0..2ae55d9e91bde6380a145fa2a9eacd00360ad881 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Dhivehi (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2019-11-10 15:04+0000\n"
 "Last-Translator: Krock <mk939@ymail.com>\n"
 "Language-Team: Dhivehi <https://hosted.weblate.org/projects/minetest/"
@@ -59,11 +59,6 @@ msgstr "އަލުން ސްޕައުންވޭ"
 msgid "You died"
 msgstr "މަރުވީ"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "މަރުވީ"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -93,6 +88,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 #, fuzzy
 msgid "An error occurred in a Lua script:"
@@ -302,6 +301,10 @@ msgstr "އަޅާ"
 msgid "Install missing dependencies"
 msgstr "ލާޒިމުނޫން ޑިޕެންޑެންސީތައް:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -631,7 +634,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -744,15 +747,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: file: \"$1\""
-msgstr "މޮޑް އަޚާ: ފައިލް:\"1$\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1133,10 +1127,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1169,7 +1159,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1198,7 +1188,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1239,14 +1229,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1268,6 +1250,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "މޮޑެއްފަދަ ލުއޭ ސްކްރިޕްޓެއްގައި މައްސަލައެއް ދިމާވެއްޖެ:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1277,6 +1269,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr "އަނިޔާވުން ޖައްސާފައި"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1286,6 +1294,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr "އަނިޔާވުން ޖައްސާފައި"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1299,6 +1311,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr "އަނިޔާވުން ޖައްސާފައި"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1307,6 +1323,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1330,6 +1350,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1539,6 +1564,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1873,6 +1913,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "$1 ނޭޅުނު"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2069,7 +2118,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2279,6 +2329,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2546,6 +2600,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2579,7 +2637,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2598,6 +2656,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2673,6 +2737,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2765,7 +2845,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2844,8 +2924,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2963,6 +3043,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3009,7 +3093,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3037,13 +3128,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3128,6 +3212,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3312,11 +3402,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3325,6 +3419,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3384,10 +3489,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3436,7 +3537,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3868,7 +3969,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3952,7 +4053,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4781,7 +4882,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5080,7 +5181,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5091,6 +5192,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5215,7 +5320,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5239,11 +5344,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5266,17 +5373,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5379,9 +5482,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5674,26 +5777,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5784,7 +5879,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5889,6 +5984,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5999,7 +6102,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6017,7 +6120,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6086,7 +6189,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6179,6 +6282,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6249,7 +6356,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6432,6 +6539,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6453,7 +6564,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6461,14 +6572,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6595,24 +6699,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6637,6 +6723,10 @@ msgstr ""
 #~ msgid "FPS in pause menu"
 #~ msgstr "ޕޯސް މެނޫގައި އެފް.ޕީ.އެސް"
 
+#, fuzzy
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "މޮޑް އަޚާ: ފައިލް:\"1$\""
+
 #, fuzzy
 #~ msgid "Main menu style"
 #~ msgstr "މެއިން މެނޫ ސްކްރިޕްޓް"
@@ -6657,5 +6747,9 @@ msgstr ""
 #~ msgid "Select Package File:"
 #~ msgstr "މޮޑްގެ ފައިލް އިހްތިޔާރުކުރޭ:"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "މަރުވީ"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index e0a5d314dfecbc79e68a68db5403133c91516bc7..2bf5854e6eadc4524211a55a4e1c6e5a2b3ef50d 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Greek (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-06-07 14:33+0000\n"
 "Last-Translator: THANOS SIOURDAKIS <siourdakisthanos@gmail.com>\n"
 "Language-Team: Greek <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -59,11 +59,6 @@ msgstr ""
 msgid "You died"
 msgstr "Πέθανες"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Πέθανες"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -93,6 +88,10 @@ msgstr ""
 msgid "OK"
 msgstr "Εντάξει"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Ένα σφάλμα προέκυψε σε ένα σενάριο Lua:"
@@ -291,6 +290,10 @@ msgstr "Εγκατάσταση $1"
 msgid "Install missing dependencies"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -616,7 +619,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -726,14 +729,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Εγκατάσταση: αρχείο: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1101,10 +1096,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1137,7 +1128,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1166,7 +1157,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1207,14 +1198,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Διεύθυνση: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1236,6 +1219,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr "- Όνομα Διακομιστή: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Παρουσιάστηκε σφάλμα:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1244,6 +1237,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1252,6 +1261,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1264,6 +1277,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1272,6 +1289,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Συνέχεια"
@@ -1295,6 +1316,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1487,6 +1513,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1821,6 +1862,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2016,7 +2065,8 @@ msgid "Muted"
 msgstr "Σε σίγαση"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Ένταση ήχου: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2223,6 +2273,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2489,6 +2543,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Εντολή"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2522,7 +2581,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2541,6 +2600,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2616,6 +2681,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2707,7 +2788,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2784,8 +2865,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2903,6 +2984,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2949,7 +3034,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2977,13 +3069,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3068,6 +3153,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3252,11 +3343,15 @@ msgid "Font size"
 msgstr "Μέγεθος γραμματοσειράς"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3265,6 +3360,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3324,10 +3430,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3376,7 +3478,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3808,7 +3910,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3892,7 +3994,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4721,7 +4823,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5014,7 +5116,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5025,6 +5127,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5146,7 +5252,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5170,11 +5276,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5197,17 +5305,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5310,9 +5414,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5605,26 +5709,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5715,7 +5811,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5820,6 +5916,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5930,7 +6034,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5948,7 +6052,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6017,7 +6121,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6110,6 +6214,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6180,7 +6288,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6363,6 +6471,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6384,7 +6496,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6392,14 +6504,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6525,24 +6630,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6561,6 +6648,9 @@ msgstr ""
 #~ msgid "Credits"
 #~ msgstr "Μνείες"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Εγκατάσταση: αρχείο: \"$1\""
+
 #~ msgid "Name / Password"
 #~ msgstr "Όνομα / Κωδικός"
 
@@ -6570,5 +6660,9 @@ msgstr ""
 #~ msgid "Special key"
 #~ msgstr "Ειδικό πλήκτρο"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Πέθανες"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "needs_fallback_font"
index 24cf6ebbc7646a00be779f3e181c9ed96671ca6f..cbb13b90424eb7b6092550615e6608a37ed493c4 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Esperanto (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-05-31 21:42+0000\n"
-"Last-Translator: Tirifto <tirifto@posteo.cz>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-10-05 08:09+0000\n"
+"Last-Translator: phlostically <phlostically@mailinator.com>\n"
 "Language-Team: Esperanto <https://hosted.weblate.org/projects/minetest/"
 "minetest/eo/>\n"
 "Language: eo\n"
@@ -12,7 +12,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.9-dev\n"
 
 #: builtin/client/chatcommands.lua
 #, fuzzy
@@ -20,33 +20,28 @@ msgid "Clear the out chat queue"
 msgstr "Maksimumo da atendantaj elaj mesaĝoj"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Babilaj komandoj"
+msgstr "Malplena komando."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Eliri al menuo"
+msgstr "Eliri al ĉefmenuo"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Loka komando"
+msgstr "Nevalida komando: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Donita komando: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Ludo por unu"
+msgstr "Listigi enretajn ludantojn"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Ludo por unu"
+msgstr "Enretaj ludantoj: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
@@ -54,7 +49,7 @@ msgstr ""
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Ĉi tiun komandon malŝaltis servilo."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,28 +59,21 @@ msgstr "Renaskiĝi"
 msgid "You died"
 msgstr "Vi mortis"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Vi mortis"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Loka komando"
+msgstr "Uzeblaj komandoj:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Loka komando"
+msgstr "Uzeblaj komandoj: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Komando ne uzeblas: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Trovu helpon pri komandoj"
 
 #: builtin/common/chatcommands.lua
 msgid ""
@@ -94,12 +82,17 @@ msgstr ""
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <komando>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "Bone"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Komando ne uzeblas: "
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Eraris Lua-skripto:"
@@ -302,6 +295,11 @@ msgstr "Instali $1"
 msgid "Install missing dependencies"
 msgstr "Instali mankantajn dependaĵojn"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Instalo: Nesubtenata dosierspeco «$1» aŭ rompita arĥivo"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -632,7 +630,8 @@ msgid "Offset"
 msgstr "Deŝovo"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Persisteco"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -743,14 +742,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Instali modifaĵon: Ne povas trovi ĝustan dosierujan nomon por modifaĵaro $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Instalo: Nesubtenata dosierspeco «$1» aŭ rompita arĥivo"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instali: dosiero: «$1»"
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Ne povas trovi validan modifaĵon aŭ modifaĵaron"
@@ -786,16 +777,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Pri"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Aktivaj kontribuantoj"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Aktiva senda amplekso de objektoj"
+msgstr "Aktiva bildigilo:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -930,9 +920,8 @@ msgid "Start Game"
 msgstr "Ekigi ludon"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "– Adreso: "
+msgstr "Adreso"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -963,7 +952,7 @@ msgstr "Ŝati"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Neakordaj serviloj"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -974,16 +963,14 @@ msgid "Ping"
 msgstr "Retprokrasto"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Enlistigi servilon"
+msgstr "Publikaj serviloj"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Reŝargi"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Priskribo pri servilo"
 
@@ -1028,13 +1015,12 @@ msgid "Connected Glass"
 msgstr "Ligata vitro"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Tipara ombro"
+msgstr "Dinamikaj ombroj"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dinamikaj ombroj: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1042,15 +1028,15 @@ msgstr "Ŝikaj folioj"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Alta"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Malalta"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Mezalta"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1124,10 +1110,6 @@ msgstr "Glata lumado"
 msgid "Texturing:"
 msgstr "Teksturado:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Por uzi ombrigilojn, OpenGL-pelilo estas necesa."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Nuanca mapado"
@@ -1142,11 +1124,11 @@ msgstr "Trilineara filtrilo"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Altega"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Malaltega"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1160,7 +1142,7 @@ msgstr "Ondantaj fluaĵoj"
 msgid "Waving Plants"
 msgstr "Ondantaj plantoj"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Konekto eltempiĝis."
 
@@ -1189,7 +1171,8 @@ msgid "Connection error (timed out?)"
 msgstr "Konekta eraro (ĉu eltempiĝo?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Ne povis trovi aŭ enlegi ludon \""
 
 #: src/client/clientlauncher.cpp
@@ -1232,14 +1215,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "– Adreso: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "– Krea reĝimo: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "– Difekto: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "– Reĝimo: "
@@ -1261,6 +1236,16 @@ msgstr "– LkL: "
 msgid "- Server Name: "
 msgstr "– Nomo de servilo: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Eraro okazis:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Memaga pluigo malŝaltita"
@@ -1269,6 +1254,22 @@ msgstr "Memaga pluigo malŝaltita"
 msgid "Automatic forward enabled"
 msgstr "Memaga pluigo ŝaltita"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Ĝisdatigo de vidpunkto malŝaltita"
@@ -1277,6 +1278,10 @@ msgstr "Ĝisdatigo de vidpunkto malŝaltita"
 msgid "Camera update enabled"
 msgstr "Ĝisdatigo de vidpunkto ŝaltita"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Ŝanĝi pasvorton"
@@ -1289,6 +1294,11 @@ msgstr "Glita vidpunkto malŝaltita"
 msgid "Cinematic mode enabled"
 msgstr "Glita vidpunkto ŝaltita"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Klienta modifado"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Klient-flanka skriptado malŝaltita"
@@ -1297,6 +1307,10 @@ msgstr "Klient-flanka skriptado malŝaltita"
 msgid "Connecting to server..."
 msgstr "Konektante al servilo…"
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Daŭrigi"
@@ -1334,6 +1348,11 @@ msgstr ""
 "– Musrado: elekti portaĵon\n"
 "– %s: babili\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Kreante klienton…"
@@ -1463,9 +1482,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Mapeto nuntempe malŝaltita de ludo aŭ modifaĵo"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Ludo por unu"
+msgstr "Ludo por pluraj ludantoj"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1539,6 +1557,21 @@ msgstr "Sonsistemo ne estas subtenata de ĉi tiu muntaĵo"
 msgid "Sound unmuted"
 msgstr "Malsilentigite"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1873,6 +1906,15 @@ msgstr "Mapeto en supraĵa reĝimo, zomo ×%d"
 msgid "Minimap in texture mode"
 msgstr "Mapeto en tekstura reĝimo"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Malsukcesis elŝuti $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Pasvortoj ne kongruas!"
@@ -2074,7 +2116,8 @@ msgid "Muted"
 msgstr "Silentigita"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Laŭteco: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2328,6 +2371,10 @@ msgstr ""
 "Ĝustigi punktojn cole al via ekrano (ekster X11/Android), ekzemple por "
 "kvarmilaj ekranoj."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2624,6 +2671,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Sojlo de babilaj mesaĝoj antaŭ forpelo"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Babilaj komandoj"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "Grandeco de babiluja tiparo"
@@ -2657,8 +2709,9 @@ msgid "Chat toggle key"
 msgstr "Babila baskula klavo"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Babilaj komandoj"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Babilo montrita"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2676,6 +2729,12 @@ msgstr "Klavo de glita vidpunkto"
 msgid "Clean transparent textures"
 msgstr "Puraj travideblaj teksturoj"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Kliento"
@@ -2721,9 +2780,8 @@ msgid "Colored fog"
 msgstr "Kolora nebulo"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Kolora nebulo"
+msgstr "Koloraj ombroj"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2766,6 +2824,38 @@ msgstr ""
 msgid "Command key"
 msgstr "Komanda klavo"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Nivelo de desigo per ZLib uzota por densigi mondopecojn dum konservado sur "
+"disko.\n"
+"-1 - la implicita nivelo de densigo per Zlib\n"
+"0 - neniu densigo, plej rapida\n"
+"9 - plej bona densigo, plej malrapida\n"
+"(niveloj 1-3 uzas la \"rapidan\" metodon de Zlib; 4-9 uzas la ordinaran "
+"metodon)"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Nivelo de desigo per ZLib uzota por densigi mondopecojn dum sendado al "
+"kliento.\n"
+"-1 - la implicita nivelo de densigo per Zlib\n"
+"0 - neniu densigo, plej rapida\n"
+"9 - plej bona densigo, plej malrapida\n"
+"(niveloj 1-3 uzas la \"rapidan\" metodon de Zlib; 4-9 uzas la ordinaran "
+"metodon)"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Kunfandi vitron"
@@ -2863,9 +2953,10 @@ msgid "Crosshair alpha"
 msgstr "Travidebleco de celilo"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Travidebleco de celilo (maltravidebleco, inter 0 kaj 255).\n"
 "Ankaŭ determinas la koloron de la celilo de objekto"
@@ -2948,8 +3039,8 @@ msgstr "Implicita grandeco de la kolumno"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3078,6 +3169,10 @@ msgstr "Malŝalti senartifikigon"
 msgid "Disallow empty passwords"
 msgstr "Malpermesi malplenajn pasvortojn"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Domajna nomo de servilo montrota en la listo de serviloj."
@@ -3128,7 +3223,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3156,13 +3258,6 @@ msgstr "Ŝalti modifaĵan sekurecon"
 msgid "Enable players getting damage and dying."
 msgstr "Ŝalti difektadon kaj mortadon de ludantoj."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Ŝalti hazardan uzulan enigon (nur por testado)."
@@ -3196,7 +3291,7 @@ msgid ""
 "expecting."
 msgstr ""
 "Ŝalti por malpermesi konekton de malnovaj klientoj.\n"
-"Malnovaj klientoj estas kongruaj tiel, ke ili ne fiaskas konektante al novaj "
+"Malnovaj klientoj estas akordaj tiel, ke ili ne fiaskas konektante al novaj "
 "serviloj,\n"
 "sed eble ili ne subtenos ĉiujn atendatajn funkciojn."
 
@@ -3273,6 +3368,12 @@ msgstr ""
 "ne funkcios.\n"
 "Ŝanĝo de ĉi tiu agordo postulos restartigon."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Intervalo inter presoj de profilaj datenoj de la motoro"
@@ -3477,11 +3578,17 @@ msgid "Font size"
 msgstr "Tipara grandeco"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Grando de la implicita tiparo, punkte (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Grandeco de la egallarĝa tiparo, punkte (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3492,6 +3599,17 @@ msgstr ""
 "Grandeco de tiparo de freŝa babila teksto kaj babilujo en punktoj (pt).\n"
 "Valoro 0 uzos la implicitan grandecon de tiparo."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3554,10 +3672,6 @@ msgstr "Speco de fraktalo"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Ono de la videbla distanco, ekde kiu nebulo bildiĝas"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Tiparoj «FreeType»"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3611,10 +3725,11 @@ msgid "Global callbacks"
 msgstr "Mallokaj revokoj"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Ĉieaj atributoj de mondestigo.\n"
 "En mondestigo v6, la parametro «decorations» regas ĉiujn ornamojn\n"
@@ -4105,7 +4220,8 @@ msgstr ""
 "Ĉi tion normale bezonas nur evoluigistoj de kerno/primitivoj"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Ekzameni babilajn komandojn je registriĝo."
 
 #: src/settings_translation_file.cpp
@@ -4198,7 +4314,8 @@ msgid "Joystick button repetition interval"
 msgstr "Ripeta periodo de stirstangaj klavoj"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+#, fuzzy
+msgid "Joystick dead zone"
 msgstr "Nerespondema zono de stirstango"
 
 #: src/settings_translation_file.cpp
@@ -5310,7 +5427,7 @@ msgstr "Intervaloj inter konservoj de mondo"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "Longeco de fluaĵa agociklo"
 
 #: src/settings_translation_file.cpp
@@ -5631,7 +5748,8 @@ msgid "Mod channels"
 msgstr "Kanaloj por modifaĵoj"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "Ŝanĝas la grandecon de eroj de la travida fasado."
 
 #: src/settings_translation_file.cpp
@@ -5642,6 +5760,11 @@ msgstr "Dosierindiko al egallarĝa tiparo"
 msgid "Monospace font size"
 msgstr "Grandeco de egalspaca tiparo"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Grandeco de egalspaca tiparo"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Bruo de monta alteco"
@@ -5786,9 +5909,10 @@ msgstr ""
 "uzantoj, la optimuma agordo eble estos «1»."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Nombro da aldonaj mondopecoj legontaj de «/clearobjects» je unu fojo.\n"
@@ -5820,10 +5944,13 @@ msgstr ""
 "fenestro estas malfermita."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5855,10 +5982,9 @@ msgid "Path to texture directory. All textures are first searched from here."
 msgstr "Dosierindiko al teksturoj. Ĉiuj teksturoj estas unue serĉataj tie."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Dosierindiko al la implicita tiparo.\n"
@@ -5868,10 +5994,9 @@ msgstr ""
 "La reenpaŝa tiparo uziĝos se la tiparo ne povas enlegiĝi."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Dosierindiko al la egallarĝa tiparo.\n"
@@ -5933,9 +6058,8 @@ msgid "Player versus player"
 msgstr "Ludanto kontraŭ ludanto"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Dulineara filtrado"
+msgstr "Poisson-filtrado"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5988,11 +6112,12 @@ msgid "Prometheus listener address"
 msgstr "Aŭskulta adreso de Prometheus"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Aŭskulta adreso de Prometheus.\n"
 "Se Minetest estas tradukita kun la elekteblo ENABLE_PROMETHEUS ŝaltita,\n"
@@ -6334,26 +6459,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6438,7 +6555,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Forto de ombro"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6461,7 +6578,8 @@ msgstr ""
 "Rerulo necesas post la ŝanĝo."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+#, fuzzy
+msgid "Show name tag backgrounds by default"
 msgstr "Implicite montri fonojn de nometikedoj"
 
 #: src/settings_translation_file.cpp
@@ -6555,9 +6673,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Rapido de kaŝirado, en monderoj sekunde."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Travidebleco de tipara ombro"
+msgstr "Radiuso de mola ombro"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6585,6 +6702,14 @@ msgstr ""
 "Notu, ke modifaĵoj aŭ ludoj povas eksplicite agordi kolumnograndojn por iuj "
 "(aŭ ĉiuj) portaĵoj."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6719,7 +6844,7 @@ msgstr "Indiko al teksturoj"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6743,7 +6868,8 @@ msgid "The URL for the content repository"
 msgstr "URL al la deponejo de enhavo"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+#, fuzzy
+msgid "The dead zone of the joystick"
 msgstr "La nerespondema zono de la stirstango"
 
 #: src/settings_translation_file.cpp
@@ -6819,7 +6945,6 @@ msgstr ""
 "Ĉi tio devas esti agordita kune kun active_object_send_range_blocks."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6828,8 +6953,8 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"La bildiga internaĵo por Irrlicht.\n"
-"Rerulo necesas post ĉi tiu ŝanĝo.\n"
+"La bildiga internaĵo.\n"
+"Relanĉo necesas post ĉi tiu ŝanĝo.\n"
 "Rimarko: Sur Androido, restu ĉe OGLES1, se vi ne certas! Aplikaĵo alie "
 "povus\n"
 "malsukcesi ruliĝon. Sur aliaj sistemoj, OpenGL estas rekomendata.\n"
@@ -6837,9 +6962,10 @@ msgstr ""
 "(eksperimente)"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Sentemo de la stirstangaj aksoj por movadi la\n"
 "enludan vidamplekson."
@@ -6956,6 +7082,10 @@ msgstr "Prokrasto de ŝpruchelpilo"
 msgid "Touch screen threshold"
 msgstr "Sojlo de tuŝekrano"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Bruo de arboj"
@@ -7031,8 +7161,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Uzi dulinearan filtradon skalante teksturojn."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7240,6 +7371,11 @@ msgstr "Longo de ondoj de ondantaj fluaĵoj"
 msgid "Waving plants"
 msgstr "Ondantaj plantoj"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Koloro de elektujo"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7269,7 +7405,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7285,17 +7421,9 @@ msgstr ""
 "grandigado de monde laŭigitaj teksturoj."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Ĉu tiparoj de FreeType uziĝas; postulas entradukitan subtenon de FreeType.\n"
-"Malŝaltite, ĉi tio anstataŭe uzigas tiparojn bitbildajn kaj XML-vektorajn."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 "Ĉu implicite montri fonojn de nometikedoj.\n"
@@ -7348,9 +7476,9 @@ msgstr ""
 "Ĉu montri erarserĉajn informojn de la kliento (efikas samkiel premo de F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Larĝeco de la fenestro je ĝia komenca grando."
+msgstr ""
+"Larĝo de la fenestro je ĝia komenca grando. Ignorata en plenekrana reĝimo."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7449,51 +7577,24 @@ msgstr "Y-nivelo de malsupra tereno kaj marfundo."
 msgid "Y-level of seabed."
 msgstr "Y-nivelo de marplanko."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Nivelo de desigo per ZLib uzota por densigi mondopecojn dum konservado sur "
-"disko.\n"
-"-1 - la implicita nivelo de densigo per Zlib\n"
-"0 - neniu densigo, plej rapida\n"
-"9 - plej bona densigo, plej malrapida\n"
-"(niveloj 1-3 uzas la \"rapidan\" metodon de Zlib; 4-9 uzas la ordinaran "
-"metodon)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Nivelo de desigo per ZLib uzota por densigi mondopecojn dum sendado al "
-"kliento.\n"
-"-1 - la implicita nivelo de densigo per Zlib\n"
-"0 - neniu densigo, plej rapida\n"
-"9 - plej bona densigo, plej malrapida\n"
-"(niveloj 1-3 uzas la \"rapidan\" metodon de Zlib; 4-9 uzas la ordinaran "
-"metodon)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Tempolimo de dosiere elŝuto de cURL"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL tempolimo"
+msgstr "Interaga tempolimo de cURL"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "Samtempa limo de cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "– Krea reĝimo: "
+
+#~ msgid "- Damage: "
+#~ msgstr "– Difekto: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7669,6 +7770,9 @@ msgstr "Samtempa limo de cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Grandeco de la reenpaŝa tiparo, punkte (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Tiparoj «FreeType»"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Kolornombro tutekrane"
 
@@ -7687,6 +7791,9 @@ msgstr "Samtempa limo de cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "Subteno de IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instali: dosiero: «$1»"
+
 #~ msgid "Lava depth"
 #~ msgstr "Lafo-profundeco"
 
@@ -7817,6 +7924,9 @@ msgstr "Samtempa limo de cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Tiu ĉi tiparo uziĝos por iuj lingvoj."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Por uzi ombrigilojn, OpenGL-pelilo estas necesa."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Baskuligi glitan vidpunkton"
 
@@ -7839,6 +7949,15 @@ msgstr "Samtempa limo de cURL"
 #~ msgid "Waving water"
 #~ msgstr "Ondanta akvo"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Ĉu tiparoj de FreeType uziĝas; postulas entradukitan subtenon de "
+#~ "FreeType.\n"
+#~ "Malŝaltite, ĉi tio anstataŭe uzigas tiparojn bitbildajn kaj XML-vektorajn."
+
 #, fuzzy
 #~ msgid "Y of upper limit of lava in large caves."
 #~ msgstr "Y de supera limo de grandaj kvazaŭ-hazardaj kavernoj."
@@ -7849,5 +7968,8 @@ msgstr "Samtempa limo de cURL"
 #~ msgid "Yes"
 #~ msgstr "Jes"
 
+#~ msgid "You died."
+#~ msgstr "Vi mortis."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 0551ef808d8e252f857c95d4426fedd61fad4efe..c0248b97aa051ba8ca3ddc4f50b2987e8cdec79e 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Spanish (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-06-01 18:49+0000\n"
-"Last-Translator: David Leal <halfpacho@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-23 18:54+0000\n"
+"Last-Translator: rubenwardy <rw@rubenwardy.com>\n"
 "Language-Team: Spanish <https://hosted.weblate.org/projects/minetest/"
 "minetest/es/>\n"
 "Language: es\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Tamaño máximo de la cola de salida del chat"
+msgstr "Vaciar la cola de chat de salida"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Comandos de Chat"
+msgstr "Comando vacío."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Salir al menú"
+msgstr "Salir al menú principal"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Comando local"
+msgstr "Comando inválido: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Comando emitido: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Un jugador"
+msgstr "Listar jugadores conectados"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Un jugador"
+msgstr "Jugadores conectados: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "La cola de salida del chat está ahora vacía."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Este comando está deshabilitado por el servidor."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,42 @@ msgstr "Reaparecer"
 msgid "You died"
 msgstr "Has muerto"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Has muerto"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Comando local"
+msgstr "Comandos disponibles:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Comando local"
+msgstr "Comandos disponibles: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Comando no disponible: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Obtener ayuda para los comandos"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Usa '.help <cmd>' para obtener más información, o '.help all' para mostrar "
+"todo."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "Aceptar"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Comando no disponible: "
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Ha ocurrido un error en un script de Lua:"
@@ -303,6 +297,11 @@ msgstr "Instalar $1"
 msgid "Install missing dependencies"
 msgstr "Instalar dependencias faltantes"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Instalar: Formato de archivo \"$1\" no soportado o archivo corrupto"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -635,7 +634,8 @@ msgid "Offset"
 msgstr "Compensado"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Persistencia"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -747,14 +747,6 @@ msgstr ""
 "Instalar mod: Imposible encontrar un nombre de carpeta adecuado para el "
 "paquete de mod $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Instalar: Formato de archivo \"$1\" no soportado o archivo corrupto"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instalar: Archivo: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Imposible encontrar un mod o paquete de mod"
@@ -791,16 +783,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Acerca de"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Colaboradores activos"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Rango de envío en objetos activos"
+msgstr "Renderizador activo:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -935,9 +926,8 @@ msgid "Start Game"
 msgstr "Empezar juego"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Dirección: "
+msgstr "Dirección"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -953,22 +943,20 @@ msgstr "Modo creativo"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Daño"
+msgstr "Daño / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Borrar Fav."
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favorito"
+msgstr "Favoritos"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Servidores Incompatibles"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -979,18 +967,16 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Anunciar servidor"
+msgstr "Servidores Públicos"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Actualizar"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Descripción del servidor"
+msgstr "Descripción del Servidor"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1033,13 +1019,12 @@ msgid "Connected Glass"
 msgstr "Vidrio conectado"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Sombra de la fuente"
+msgstr "Sombras dinámicas"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Sombras dinámicas: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1047,15 +1032,15 @@ msgstr "Hojas elegantes"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Bajo"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Medio"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1083,7 +1068,7 @@ msgstr "Marcar nodos"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "None"
-msgstr "Ninguno"
+msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Leaves"
@@ -1103,7 +1088,7 @@ msgstr "Pantalla:"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Settings"
-msgstr "Configuración"
+msgstr "Ajustes"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Shaders"
@@ -1129,10 +1114,6 @@ msgstr "Iluminación suave"
 msgid "Texturing:"
 msgstr "Texturizado:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Para habilitar los sombreadores debe utilizar el controlador OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Mapeado de tonos"
@@ -1147,11 +1128,11 @@ msgstr "Filtrado trilineal"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Ultra Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Muy bajo"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1165,7 +1146,7 @@ msgstr "Movimiento de líquidos"
 msgid "Waving Plants"
 msgstr "Movimiento de plantas"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Tiempo de espera de la conexión agotado."
 
@@ -1194,7 +1175,8 @@ msgid "Connection error (timed out?)"
 msgstr "Error de conexión (¿tiempo agotado?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "No se puede encontrar o cargar el juego \""
 
 #: src/client/clientlauncher.cpp
@@ -1239,14 +1221,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Dirección: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Modo creativo: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Daño: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Modo: "
@@ -1268,6 +1242,16 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Nombre del servidor: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Ha ocurrido un error:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Avance automático desactivado"
@@ -1276,6 +1260,23 @@ msgstr "Avance automático desactivado"
 msgid "Automatic forward enabled"
 msgstr "Avance automático activado"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds hidden"
+msgstr "Límites de bloque"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Actualización de la cámara desactivada"
@@ -1284,9 +1285,13 @@ msgstr "Actualización de la cámara desactivada"
 msgid "Camera update enabled"
 msgstr "Actualización de la cámara activada"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
-msgstr "Cambiar contraseña"
+msgstr ""
 
 #: src/client/game.cpp
 msgid "Cinematic mode disabled"
@@ -1296,6 +1301,11 @@ msgstr "Modo cinematográfico desactivado"
 msgid "Cinematic mode enabled"
 msgstr "Modo cinematográfico activado"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Customización del cliente"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "El Scripting en el lado del cliente está desactivado"
@@ -1304,6 +1314,10 @@ msgstr "El Scripting en el lado del cliente está desactivado"
 msgid "Connecting to server..."
 msgstr "Conectando al servidor..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Continuar"
@@ -1341,6 +1355,11 @@ msgstr ""
 "- Rueda del ratón: elegir objeto\n"
 "- %s: chat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Creando cliente..."
@@ -1470,9 +1489,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "El minimapa se encuentra actualmente desactivado por el juego o un mod"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Un jugador"
+msgstr "Multijugador"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1546,6 +1564,21 @@ msgstr "El sistema de sonido no está soportado en esta \"build\""
 msgid "Sound unmuted"
 msgstr "Sonido no silenciado"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1880,6 +1913,15 @@ msgstr "Minimapa en modo superficie, Zoom x%d"
 msgid "Minimap in texture mode"
 msgstr "Minimapa en modo textura"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Fallo al descargar $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "¡Las contraseñas no coinciden!"
@@ -1908,9 +1950,8 @@ msgid "Proceed"
 msgstr "Continuar"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Especial\" = Descender"
+msgstr "\"Aux1\" = bajar"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1922,7 +1963,7 @@ msgstr "Salto automático"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1930,7 +1971,7 @@ msgstr "Atrás"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Límites de bloque"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2083,7 +2124,8 @@ msgid "Muted"
 msgstr "Silenciado"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Volumen del sonido: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2350,6 +2392,10 @@ msgstr ""
 "Ajustar la configuración de puntos por pulgada a tu pantalla (no X11/Android "
 "sólo), por ejemplo para pantallas 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2488,13 +2534,12 @@ msgid "Autoscaling mode"
 msgstr "Modo de autoescalado"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Tecla Saltar"
+msgstr "Tecla Aux1"
 
 #: src/settings_translation_file.cpp
 msgid "Aux1 key for climbing/descending"
-msgstr ""
+msgstr "Tecla Aux1 para subir/bajar"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2651,6 +2696,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Umbral de expulsión por mensajes"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Comandos de Chat"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "Tamaño de la fuente del chat"
@@ -2684,8 +2734,9 @@ msgid "Chat toggle key"
 msgstr "Tecla alternativa para el chat"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Comandos de Chat"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Chat visible"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2703,6 +2754,12 @@ msgstr "Tecla modo cinematográfico"
 msgid "Clean transparent textures"
 msgstr "Limpiar texturas transparentes"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Cliente"
@@ -2748,9 +2805,8 @@ msgid "Colored fog"
 msgstr "Niebla colorida"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Niebla colorida"
+msgstr "Sombras coloridas"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2793,6 +2849,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Tecla comando"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Conectar vidrio"
@@ -2893,9 +2965,10 @@ msgid "Crosshair alpha"
 msgstr "Opacidad del punto de mira"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Alfa del punto de mira (opacidad, entre 0 y 255).\n"
 "También controla el color del objeto punto de mira"
@@ -2978,8 +3051,8 @@ msgstr "Tamaño por defecto del stack (Montón)"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3109,6 +3182,10 @@ msgstr "Desactivar Anticheat"
 msgid "Disallow empty passwords"
 msgstr "No permitir contraseñas vacías"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3159,10 +3236,25 @@ msgstr ""
 "El soporte es experimental y la API puede cambiar."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Habilitar filtrado \"poisson disk\".\n"
+"Si el valor es \"verdadero\", utiliza \"poisson disk\" para proyectar "
+"sombras suaves. De otro modo utiliza filtrado PCF."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Enable colored shadows. \n"
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Habilitar las sombras a color.\n"
+"Si el valor es verdadero los nodos traslúcidos proyectarán sombras a color. "
+"Esta opción usa muchos recursos."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3188,13 +3280,6 @@ msgstr "Activar seguridad de mods"
 msgid "Enable players getting damage and dying."
 msgstr "Habilitar daños y muerte de jugadores."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Habilitar entrada aleatoria (solo usar para pruebas)."
@@ -3307,6 +3392,12 @@ msgstr ""
 "los controles de sonido el juego no serán funcionales.\n"
 "Cambiar esta configuración requiere un reinicio."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Intervalo de impresión de datos del perfil del motor"
@@ -3371,12 +3462,11 @@ msgid "Fast movement"
 msgstr "Movimiento rápido"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Movimiento rápido (por medio de tecla de \"Uso\").\n"
+"Movimiento rápido (por medio de tecla de \"Aux1\").\n"
 "Requiere privilegio \"fast\" (rápido) en el servidor."
 
 #: src/settings_translation_file.cpp
@@ -3513,11 +3603,17 @@ msgid "Font size"
 msgstr "Tamaño de la fuente"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Tamaño de la fuente por defecto en punto (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Tamaño de la fuente del monoespacio en punto (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3529,6 +3625,17 @@ msgstr ""
 "en punto (pt).\n"
 "El valor 0 utilizará el tamaño de fuente predeterminado."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3593,10 +3700,6 @@ msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 "Fracción de la distancia visible en la que la niebla se empieza a renderizar"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Fuentes FreeType"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3652,10 +3755,11 @@ msgid "Global callbacks"
 msgstr "Llamadas globales"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Atributos del generador de mapas globales.\n"
 "En el generador de mapas V6 la opción (o marcador) \"decorations\" controla "
@@ -4002,14 +4106,13 @@ msgstr ""
 "a fin de no malgastar potencia de CPU sin beneficio."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Si está desactivado, la tecla \"especial\" se utiliza para volar rápido si "
-"tanto el modo de vuelo como el modo rápido están\n"
-"habilitados."
+"Si está desactivado, la tecla \"Aux1\" se utiliza para volar rápido si el "
+"modo\n"
+"de vuelo y el modo rápido están habilitados."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4108,6 +4211,8 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Si la ejecución de un comando toma más tiempo del especificado en\n"
+"segundos, agrega la información del tiempo al mensaje del comando"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4166,7 +4271,8 @@ msgstr ""
 "Esto solo suele ser necesario para los colaboradores principales o integrados"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Instrumento de comandos del chat en el registro."
 
 #: src/settings_translation_file.cpp
@@ -4261,7 +4367,8 @@ msgid "Joystick button repetition interval"
 msgstr "Intervalo de repetición del botón del Joystick"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+#, fuzzy
+msgid "Joystick dead zone"
 msgstr "Zona muerta del joystick"
 
 #: src/settings_translation_file.cpp
@@ -5342,7 +5449,7 @@ msgstr ""
 "Valleys.\n"
 "'altitude_chill': Reduce el calor con la altitud.\n"
 "'humid_rivers': Aumenta la humedad alrededor de ríos.\n"
-"'vary_river_depth': Si está activo, la baja humedad y alto calor causan que "
+"'vary_river_depth': Si está activo, la baja humedad y alto calor causan que\n"
 "los ríos sean poco profundos y ocasionalmente secos.\n"
 "'altitude_dry': Reduce la humedad con la altitud."
 
@@ -5351,40 +5458,29 @@ msgid "Map generation attributes specific to Mapgen v5."
 msgstr "Atributos de generación de mapas específicos al generador de mapas v5."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen v6.\n"
 "The 'snowbiomes' flag enables the new 5 biome system.\n"
 "When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n"
 "the 'jungles' flag is ignored."
 msgstr ""
-"Atributos del generador de mapas globales.\n"
-"En el generador de mapas V6 la opción (o marcador) \"decorations\" controla "
-"todos los elementos decorativos excepto los árboles y la hierba de la "
-"jungla, en todos los otros generadores de mapas esta opción controla todas "
-"las decoraciones.\n"
-"Las opciones que no son incluidas en el texto con la cadena de opciones no "
-"serán modificadas y mantendrán su valor por defecto.\n"
-"Las opciones que comienzan con el prefijo \"no\" son utilizadas para "
-"inhabilitar esas opciones."
+"Atributos específicos para la generación de Mapgen v6.\n"
+"La opción 'snowbiomes' activa el nuevo sistema de generación de 5 biomas.\n"
+"Cuando la opción 'snowbiomes' está activada, las junglas se activan "
+"automáticamente y\n"
+"la opción 'jungles' es ignorada."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen v7.\n"
 "'ridges': Rivers.\n"
 "'floatlands': Floating land masses in the atmosphere.\n"
 "'caverns': Giant caves deep underground."
 msgstr ""
-"Atributos del generador de mapas globales.\n"
-"En el generador de mapas V6 la opción (o marcador) \"decorations\" controla "
-"todos los elementos decorativos excepto los árboles y la hierba de la "
-"jungla, en todos los otros generadores de mapas esta opción controla todas "
-"las decoraciones.\n"
-"Las opciones que no son incluidas en el texto con la cadena de opciones no "
-"serán modificadas y mantendrán su valor por defecto.\n"
-"Las opciones que comienzan con el prefijo \"no\" son utilizadas para "
-"inhabilitar esas opciones."
+"Atributos específicos para la generación de Mapgen v7.\n"
+"'ridges': Rios.\n"
+"'floatlands': Masas de tierra flotantes en la atmósfera.\n"
+"'caverns': Cavernas gigantes subterráneo profundo."
 
 #: src/settings_translation_file.cpp
 msgid "Map generation limit"
@@ -5396,8 +5492,8 @@ msgstr "Intervalo de guardado de mapa"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
-msgstr "Tick de actualización de los líquidos"
+msgid "Map shadows update frames"
+msgstr "Tiempo de actualización de mapa"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5512,7 +5608,7 @@ msgstr "FPS máximo cuando el juego está pausado."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Distancia máxima para renderizar las sombras."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5601,18 +5697,17 @@ msgid ""
 "try reducing it, but don't reduce it to a number below double of targeted\n"
 "client number."
 msgstr ""
-"Número máximo de paquetes enviados por paso de envío. Si tiene una conexión "
-"lenta, intente reducirlo, pero no lo reduzca a un número menor al doble del "
+"Número máximo de paquetes enviados por paso de envío. Si tiene una conexión\n"
+"lenta, intente reducirlo, pero no lo reduzca a un número menor al doble del\n"
 "número de cliente objetivo."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum number of players that can be connected simultaneously."
-msgstr "Cantidad de bloques que flotan simultáneamente por cliente."
+msgstr "Número máximo de jugadores que se pueden conectar simultáneamente."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of recent chat messages to show"
-msgstr "Número máximo de mensajes del chat recientes a mostrar."
+msgstr "Número máximo de mensajes del chat recientes a mostrar"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of statically stored objects in a block."
@@ -5620,7 +5715,7 @@ msgstr "Número máximo de objetos almacenados estáticamente en un bloque."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum objects per block"
-msgstr "Objetos máximos por bloque."
+msgstr "Objetos máximos por bloque"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5650,19 +5745,20 @@ msgstr ""
 "ilimitado."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Tiempo máximo en ms que puede demorar una descarga (por ejemplo, la descarga "
-"de un mod)."
+"Tiempo máximo que puede tardar la descarga de archivo (p.ej. una descarga de "
+"mod) en milisegundos."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Tiempo máximo que puede tardar la solicitud interactiva (p.ej. una búsqueda "
+"de lista de servidores) en milisegundos."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5711,11 +5807,11 @@ msgstr "Ruido 3D que determina la cantidad de mazmorras por chunk."
 
 #: src/settings_translation_file.cpp
 msgid "Minimum limit of random number of small caves per mapchunk."
-msgstr ""
+msgstr "Límite mínimo del número aleatorio de cavernas pequeñas por mapchunk."
 
 #: src/settings_translation_file.cpp
 msgid "Minimum texture size"
-msgstr ""
+msgstr "Tamaño mínimo de textura"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -5727,7 +5823,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5738,6 +5834,11 @@ msgstr "Ruta de fuente monoespaciada"
 msgid "Monospace font size"
 msgstr "Tamaño de fuente monoespaciada"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Tamaño de fuente monoespaciada"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5752,7 +5853,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Mountain zero level"
-msgstr ""
+msgstr "Nivel cero de montañas"
 
 #: src/settings_translation_file.cpp
 msgid "Mouse sensitivity"
@@ -5806,7 +5907,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Near plane"
-msgstr ""
+msgstr "Plano cercano"
 
 #: src/settings_translation_file.cpp
 msgid "Network"
@@ -5863,7 +5964,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5887,11 +5988,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5914,17 +6017,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5992,6 +6091,8 @@ msgid ""
 "Port to connect to (UDP).\n"
 "Note that the port field in the main menu overrides this setting."
 msgstr ""
+"Puerto de conectarse (UDP).\n"
+"Nota que el campo de puerto en el menú principal anula esta configuración."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6001,7 +6102,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Prevent mods from doing insecure things like running shell commands."
-msgstr ""
+msgstr "Evitar que mods hagan cosas inseguras como ejecutar comandos de shell."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6015,7 +6116,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Profiler"
-msgstr ""
+msgstr "Perfilador"
 
 #: src/settings_translation_file.cpp
 msgid "Profiler toggle key"
@@ -6032,9 +6133,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6054,7 +6155,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Random input"
-msgstr ""
+msgstr "Entrada aleatoria"
 
 #: src/settings_translation_file.cpp
 msgid "Range select key"
@@ -6065,17 +6166,16 @@ msgid "Recent Chat Messages"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Regular font path"
-msgstr "Ruta de fuentes"
+msgstr "Ruta de fuente regular"
 
 #: src/settings_translation_file.cpp
 msgid "Remote media"
-msgstr ""
+msgstr "Medios remotos"
 
 #: src/settings_translation_file.cpp
 msgid "Remote port"
-msgstr ""
+msgstr "Puerto remoto"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6085,7 +6185,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Replaces the default main menu with a custom one."
-msgstr ""
+msgstr "Sustituye el menú principal por defecto con uno personalizado."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -6354,26 +6454,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6479,7 +6571,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr "Fuente en negrita por defecto"
 
 #: src/settings_translation_file.cpp
@@ -6586,6 +6678,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6697,7 +6797,7 @@ msgstr "Ruta de la textura"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6715,7 +6815,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6784,7 +6884,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6879,6 +6979,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr "Límite de ruido de playa"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6949,7 +7053,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7140,6 +7244,10 @@ msgstr "Oleaje en el agua"
 msgid "Waving plants"
 msgstr "Movimiento de plantas"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7161,7 +7269,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7169,14 +7277,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7303,24 +7404,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Tiempo de espera de descarga por cURL"
@@ -7334,6 +7417,12 @@ msgstr "Tiempo de espera de cURL"
 msgid "cURL parallel limit"
 msgstr "Límite de cURL en paralelo"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Modo creativo: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Daño: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7506,6 +7595,9 @@ msgstr "Límite de cURL en paralelo"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Tamaño de la fuente de reserva en punto (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Fuentes FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Profundidad de color en pantalla completa"
 
@@ -7524,6 +7616,9 @@ msgstr "Límite de cURL en paralelo"
 #~ msgid "IPv6 support."
 #~ msgstr "soporte IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instalar: Archivo: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "Características de la Lava"
@@ -7615,6 +7710,10 @@ msgstr "Límite de cURL en paralelo"
 #~ msgid "Strength of generated normalmaps."
 #~ msgstr "Fuerza de los mapas normales generados."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr ""
+#~ "Para habilitar los sombreadores debe utilizar el controlador OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Activar cinemático"
 
@@ -7630,5 +7729,8 @@ msgstr "Límite de cURL en paralelo"
 #~ msgid "Yes"
 #~ msgstr "Sí"
 
+#~ msgid "You died."
+#~ msgstr "Has muerto."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 90801e3195c24dcc426129313a3c72dc5ee7228a..8031c94513ef1623ae3854c0b55a5a6e42d8347e 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Estonian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-03-02 15:50+0000\n"
-"Last-Translator: Ayes <andris.sass@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-06-29 10:33+0000\n"
+"Last-Translator: Janar Leas <janarleas+ubuntuone@googlemail.com>\n"
 "Language-Team: Estonian <https://hosted.weblate.org/projects/minetest/"
 "minetest/et/>\n"
 "Language: et\n"
@@ -12,40 +12,35 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5\n"
+"X-Generator: Weblate 4.7.1-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
 msgstr ""
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Käsklused"
+msgstr "Tühi käsk."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
 msgstr "Välju menüüsse"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Kohalik käsk"
+msgstr "Väär käsk: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Anti käsklus: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Üksikmäng"
+msgstr "Võrgus mängijate loend"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Üksikmäng"
+msgstr "Mängijaid võrgus: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
@@ -53,7 +48,7 @@ msgstr ""
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Võõrustaja piiras selle käsu kasutuse."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -63,42 +58,40 @@ msgstr "Ärka ellu"
 msgid "You died"
 msgstr "Said surma"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Said surma"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Kohalik käsk"
+msgstr "Võimalikud käsud:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Kohalik käsk"
+msgstr "Võimalikud käsud: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Käsk pole saadaval: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Leia abi käskude kohta"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
-msgstr ""
+msgstr "'.help <käsk>' jagab rohkem teadmisi, ning '.help all' loetleb kõik."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <käsk>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "Valmis"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Käsk pole saadaval: "
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua skriptis ilmnes viga:"
@@ -230,17 +223,19 @@ msgstr "\"$1\" on juba olemas. Kas sa tahad seda üle kirjutada?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
-msgstr ""
+msgstr "Paigaldatakse sõltuvused $1 ja $2."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1 $2 poolt"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
 "$1 downloading,\n"
 "$2 queued"
 msgstr ""
+"$1 allalaadimisel,\n"
+"$2 ootel"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 downloading..."
@@ -248,7 +243,7 @@ msgstr "$1 allalaadimine..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr ""
+msgstr "$1 vajaliku sõltuvust polnud leida."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
@@ -296,9 +291,13 @@ msgid "Install $1"
 msgstr "Paigalda $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install missing dependencies"
-msgstr "Paigalda valikulised sõltuvused"
+msgstr "Paigalda puuduvad sõltuvused"
+
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Paigaldus: Toetamata failitüüp \"$1\" või katkine arhiiv"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -318,7 +317,6 @@ msgid "No updates"
 msgstr "Värskendusi pole"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Not found"
 msgstr "Ei leitud"
 
@@ -332,7 +330,7 @@ msgstr "Palun tee kindlaks et põhi mäng on õige."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "Ootel"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Texture packs"
@@ -630,7 +628,8 @@ msgid "Offset"
 msgstr "Nihe"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Püsivus"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -741,14 +740,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Paigalda mod: Sobiva katalooginime leidmine ebaõnnestus mod-komplektile $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Paigaldus: Toetamata failitüüp \"$1\" või katkine arhiiv"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Paigaldus: fail: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Ei leitud sobivat mod-i ega mod-komplekti"
@@ -785,7 +776,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Teavet"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
@@ -808,6 +799,8 @@ msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"Kasutaja poolsete maailmate, mängude, mod-de ning tekstuuri pakide\n"
+"kausta avamine faili-halduris."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
@@ -898,9 +891,8 @@ msgid "No world created or selected!"
 msgstr "Pole valitud ega loodud ühtegi maailma!"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Password"
-msgstr "Uus parool"
+msgstr "Salasõna"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
@@ -927,9 +919,8 @@ msgid "Start Game"
 msgstr "Alusta mängu"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Aadress: "
+msgstr "Aadress"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -945,22 +936,20 @@ msgstr "Looja"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Vigastused"
+msgstr "Vigastused mängijatelt"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Pole lemmik"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "On lemmik"
+msgstr "Lemmikud"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Ühildumatud Võõrustajad"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -971,18 +960,16 @@ msgid "Ping"
 msgstr "Viivitus"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Võõrustamise kuulutamine"
+msgstr "Avalikud võõrustajad"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Värskenda"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Võõrustaja kanal"
+msgstr "Võõrustaja kirjeldus"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1026,11 +1013,11 @@ msgstr "Ühendatud klaas"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "Elavad varjud"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Elavad varjud: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1038,15 +1025,15 @@ msgstr "Uhked lehed"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Kõrge"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Madal"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Keskmine"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1101,9 +1088,8 @@ msgid "Shaders"
 msgstr "Varjutajad"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "Shaders (experimental)"
-msgstr "Shaderid (eksperimentaalsed)"
+msgstr "Shaderid (katselised)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
@@ -1121,10 +1107,6 @@ msgstr "Sujuv valgustus"
 msgid "Texturing:"
 msgstr "Tekstureerimine:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Aktiveerimiseks varjud, nad vajavad OpenGL draiver."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tooni kaardistamine"
@@ -1139,11 +1121,11 @@ msgstr "Tri-lineaar filtreerimine"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Ülikõrge"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Vägamadal"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1157,7 +1139,7 @@ msgstr "Lainetavad vedelikud"
 msgid "Waving Plants"
 msgstr "Lehvivad taimed"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Ühendus aegus."
 
@@ -1186,7 +1168,8 @@ msgid "Connection error (timed out?)"
 msgstr "Ühenduse viga (Aeg otsas?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Ei leia ega suuda jätkata mängu \""
 
 #: src/client/clientlauncher.cpp
@@ -1229,14 +1212,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Aadress: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kujunduslik mängumood: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Valu: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Režiim: "
@@ -1258,6 +1233,16 @@ msgstr "- Üksteise vastu: "
 msgid "- Server Name: "
 msgstr "- Serveri nimi: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Ilmnes viga:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automaatne edastus keelatud"
@@ -1266,6 +1251,23 @@ msgstr "Automaatne edastus keelatud"
 msgid "Automatic forward enabled"
 msgstr "Automaatne edastus lubatud"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds hidden"
+msgstr "Klotsi piirid"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kaamera värskendamine on keelatud"
@@ -1274,6 +1276,10 @@ msgstr "Kaamera värskendamine on keelatud"
 msgid "Camera update enabled"
 msgstr "Kaamera värskendamine on lubatud"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Vaheta parooli"
@@ -1286,6 +1292,10 @@ msgstr "Filmirežiim on keelatud"
 msgid "Cinematic mode enabled"
 msgstr "Filmirežiim on lubatud"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Kliendipoolne skriptimine on keelatud"
@@ -1294,6 +1304,10 @@ msgstr "Kliendipoolne skriptimine on keelatud"
 msgid "Connecting to server..."
 msgstr "Serveriga ühenduse loomine..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Jätka"
@@ -1331,6 +1345,11 @@ msgstr ""
 "- Hiireratas: vali ese\n"
 "- %s: vestlus\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Kliendi loomine..."
@@ -1444,7 +1463,6 @@ msgid "Item definitions..."
 msgstr "Esemete määratlused..."
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "KiB/s"
 msgstr "KiB/s"
 
@@ -1453,7 +1471,6 @@ msgid "Media..."
 msgstr "Meedia..."
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "MiB/s"
 msgstr "MiB/s"
 
@@ -1462,9 +1479,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Pisikaardi keelab hetkel mäng või MOD"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Üksikmäng"
+msgstr "Hulgimängija"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1500,7 +1516,7 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Profiler graph shown"
-msgstr ""
+msgstr "Koormushinnangu kuvamine"
 
 #: src/client/game.cpp
 msgid "Remote server"
@@ -1538,6 +1554,21 @@ msgstr "See kooste ei toeta heli süsteemi"
 msgid "Sound unmuted"
 msgstr "Heli taastatud"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1554,13 +1585,13 @@ msgid "Viewing range is at minimum: %d"
 msgstr "Vaate kaugus on vähim võimalik: %d"
 
 #: src/client/game.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Volume changed to %d%%"
-msgstr "helitugevus muutetud %d%%-ks"
+msgstr "Helitugevus muutus %d%%"
 
 #: src/client/game.cpp
 msgid "Wireframe shown"
-msgstr ""
+msgstr "Raamvõrgustiku paljastus"
 
 #: src/client/game.cpp
 msgid "Zoom currently disabled by game or mod"
@@ -1576,24 +1607,24 @@ msgstr "Vestlus peidetud"
 
 #: src/client/gameui.cpp
 msgid "Chat shown"
-msgstr ""
+msgstr "Vestluse näitamine"
 
 #: src/client/gameui.cpp
 msgid "HUD hidden"
-msgstr ""
+msgstr "Liidese peitmine"
 
 #: src/client/gameui.cpp
 msgid "HUD shown"
-msgstr ""
+msgstr "Liidese näitamine"
 
 #: src/client/gameui.cpp
 msgid "Profiler hidden"
-msgstr ""
+msgstr "Koormushindaja peitmine"
 
 #: src/client/gameui.cpp
 #, c-format
 msgid "Profiler shown (page %d of %d)"
-msgstr ""
+msgstr "Koormushinnang (%d leht %d-st)"
 
 #: src/client/keycode.cpp
 msgid "Apps"
@@ -1762,11 +1793,11 @@ msgstr "OEM Tühi"
 
 #: src/client/keycode.cpp
 msgid "Page down"
-msgstr ""
+msgstr "Lehekülg alla"
 
 #: src/client/keycode.cpp
 msgid "Page up"
-msgstr ""
+msgstr "Lehekülg üles"
 
 #: src/client/keycode.cpp
 msgid "Pause"
@@ -1869,9 +1900,17 @@ msgid "Minimap in surface mode, Zoom x%d"
 msgstr "Pinnakaart, Suurendus ×%d"
 
 #: src/client/minimap.cpp
-#, fuzzy
 msgid "Minimap in texture mode"
-msgstr "Pinnakaart, Suurendus ×1"
+msgstr "Pisikaart tekstuur-laadis"
+
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "$1 allalaadimine nurjus"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
@@ -1890,15 +1929,19 @@ msgid ""
 "Please retype your password and click 'Register and Join' to confirm account "
 "creation, or click 'Cancel' to abort."
 msgstr ""
+"Oled esmakordselt liitumas selle võõrustajaga, kandes nime \"%s\".\n"
+"Kui jätkad, siis luuakse sellele võõrustajale uus konto sinu volitus "
+"andmetega.\n"
+"Trüki salasõna uuesti ning klõpsa 'Registreeru ja ühine' konto loomisega "
+"nõustumiseks, või 'Loobu' keeldumiseks."
 
 #: src/gui/guiFormSpecMenu.cpp
 msgid "Proceed"
 msgstr "Jätka"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Eriline\" = roni alla"
+msgstr "\"Aux1\" = roni alla"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1910,7 +1953,7 @@ msgstr "Automaatne hüppamine"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1918,7 +1961,7 @@ msgstr "Tagasi"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Klotsi piirid"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -1938,11 +1981,11 @@ msgstr "Konsool"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. range"
-msgstr ""
+msgstr "Vähenda ulatust"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. volume"
-msgstr ""
+msgstr "Vähenda valjust"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Double tap \"jump\" to toggle fly"
@@ -1958,7 +2001,7 @@ msgstr "Edasi"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. range"
-msgstr ""
+msgstr "Suurenda ulatust"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. volume"
@@ -1987,16 +2030,14 @@ msgid "Local command"
 msgstr "Kohalik käsk"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Mute"
-msgstr "Summuta"
+msgstr "Vaigista"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Next item"
 msgstr "Järgmine üksus"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Prev. item"
 msgstr "Eelmine asi"
 
@@ -2073,13 +2114,13 @@ msgid "Muted"
 msgstr "Vaigistatud"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Hääle Volüüm: "
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
 #: src/gui/modalMenu.cpp
-#, fuzzy
 msgid "Enter "
 msgstr "Sisesta "
 
@@ -2095,6 +2136,8 @@ msgid ""
 "(Android) Fixes the position of virtual joystick.\n"
 "If disabled, virtual joystick will center to first-touch's position."
 msgstr ""
+"(Android) Parendab virtuaalse juhtkangi asukohta.\n"
+"Kui keelatud, siis juhtkangi kese asub esmapuute kohal."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2102,6 +2145,8 @@ msgid ""
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
+"(Android) Virtuaal-juhtkangi kasutamine \"Aux1\" nupu päästmiseks.\n"
+"Kui lubatud, juhtkang päästab ka \"Aux1\" nupu kui läheb väljapoole pearingi."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2128,31 +2173,31 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of ridged mountains."
-msgstr ""
+msgstr "Kahemõõtmeline müra mis määrab seljandike kuju/suuruse."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of rolling hills."
-msgstr ""
+msgstr "Kahemõõtmeline müra mis määrab vooremaa kuju/suuruse."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of step mountains."
-msgstr ""
+msgstr "Kahemõõtmeline müra mis määrab astmikkõrgustike kuju/suuruse."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of ridged mountain ranges."
-msgstr ""
+msgstr "Kahemõõtmeline müra mis määrab seljandike ala suuruse/ilmingu."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of rolling hills."
-msgstr ""
+msgstr "Kahemõõtmeline müra mis määrab vooremaa ala suuruse/ilmingu."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of step mountain ranges."
-msgstr ""
+msgstr "Kahemõõtmeline müra mis määrab astmikkõrgendike ala suuruse/ilmingu."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that locates the river valleys and channels."
-msgstr ""
+msgstr "Kahemõõtmeline müra mis paigutab jõeorud ja kanalid."
 
 #: src/settings_translation_file.cpp
 msgid "3D clouds"
@@ -2168,7 +2213,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining giant caverns."
-msgstr ""
+msgstr "Üüratuid koopasaale määratlev kolmemõõtmeline müra."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2186,19 +2231,20 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining structure of river canyon walls."
-msgstr ""
+msgstr "Kanjonjõe järsakkaldaid määratlev kolmemõõtmeline müra."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining terrain."
-msgstr ""
+msgstr "Maastiku määratlev kolmemõõtmeline müra."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations."
 msgstr ""
+"Kolmemõõtmeline müra kaljudele, eenditele, jms. Tavaliselt väikesed erisused."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise that determines number of dungeons per mapchunk."
-msgstr ""
+msgstr "Kolmemõõtmeline müra, mis määratleb kambristike sageduse kaardijaos."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2222,27 +2268,27 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server crashes."
-msgstr ""
+msgstr "Teade kõigile külalistele, kui võõrustaja kooleb."
 
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server shuts down."
-msgstr ""
+msgstr "Teade kõigile külalistele, kui server kinni läheb."
 
 #: src/settings_translation_file.cpp
 msgid "ABM interval"
-msgstr ""
+msgstr "ABM sagedus"
 
 #: src/settings_translation_file.cpp
 msgid "ABM time budget"
-msgstr ""
+msgstr "ABM-i ajakava"
 
 #: src/settings_translation_file.cpp
 msgid "Absolute limit of queued blocks to emerge"
-msgstr ""
+msgstr "Kõrgeim piirang ilmumist ootavatele klotsiedele"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration in air"
-msgstr ""
+msgstr "Kiirendus õhus"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration of gravity, in nodes per second per second."
@@ -2281,6 +2327,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2394,9 +2444,8 @@ msgid "Autoscaling mode"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Hüppa"
+msgstr "Aux1 võti"
 
 #: src/settings_translation_file.cpp
 msgid "Aux1 key for climbing/descending"
@@ -2545,9 +2594,13 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Vestlus sõnumi väljaviskamis lävi"
+msgstr "Vestluskäskluse ajalise sõnumi lävi"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Käsklused"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2582,8 +2635,9 @@ msgid "Chat toggle key"
 msgstr "Vestluse lülitusklahv"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Käsklused"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Vestluse näitamine"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2601,6 +2655,12 @@ msgstr "Filmirežiimi klahv"
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2676,6 +2736,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Käsuklahv"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Ühenda klaasi"
@@ -2767,7 +2843,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2844,8 +2920,8 @@ msgstr "Vaike lasu hulk"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2950,9 +3026,8 @@ msgid "Desynchronize block animation"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dig key"
-msgstr "Parem klahv"
+msgstr "Kaevuri klahv"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -2966,6 +3041,10 @@ msgstr "Lülita sohituvastus välja"
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3012,7 +3091,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3040,13 +3126,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3131,6 +3210,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3315,11 +3400,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3328,6 +3417,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3387,10 +3487,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3436,15 +3532,15 @@ msgid "Global callbacks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
-"Üldised maailma-loome omadused.\n"
-"Maailma loome v6 puhul lipp 'Ilmestused' ei avalda mõju puudele ja \n"
-"tihniku rohule, kõigi teiste versioonide puhul mõjutab see lipp \n"
-"kõiki ilmestusi (nt: lilled, seened, vetikad, korallid, jne)."
+"Üldised maailma loome omadused.\n"
+"Maailma loome v6 puhul lipp 'ilmestused' ei avalda mõju puudele ja \n"
+"tihniku rohule, kõigi teistega mõjutab see lipp kõiki ilmestusi."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3875,7 +3971,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3959,7 +4055,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4793,7 +4889,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5086,7 +5182,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5097,6 +5193,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5218,7 +5318,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5242,11 +5342,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5269,17 +5371,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5308,9 +5406,8 @@ msgid "Pitch move mode"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Place key"
-msgstr "Kõrvale astumise klahv"
+msgstr "Asetamis klahv"
 
 #: src/settings_translation_file.cpp
 msgid "Place repetition interval"
@@ -5335,9 +5432,8 @@ msgid "Player versus player"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Bilineaarne filtreerimine"
+msgstr "Poissoni filtreerimine"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5384,9 +5480,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5679,26 +5775,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5745,9 +5833,8 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Kuvapildi tase"
+msgstr "Varju filtreerimis aste"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
@@ -5790,7 +5877,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5895,6 +5982,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6005,7 +6100,7 @@ msgstr "Tapeedi kaust"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6023,7 +6118,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6092,7 +6187,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6185,6 +6280,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr "Puuteekraani lävi"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6255,7 +6354,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6438,6 +6537,10 @@ msgstr "Vedeliku laine pikkus"
 msgid "Waving plants"
 msgstr "Õõtsuvad taimed"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6459,7 +6562,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6467,14 +6570,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6600,37 +6696,24 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL faili allalaadimine aegus"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL aegus"
+msgstr "cURL-i interaktiivne aegumine"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kujunduslik mängumood: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Valu: "
+
 #~ msgid "Address / Port"
 #~ msgstr "Aadress / kanal"
 
@@ -6674,6 +6757,9 @@ msgstr ""
 #~ msgid "Generate Normal Maps"
 #~ msgstr "Loo normaalkaardistusi"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Paigaldus: fail: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "Peamine"
 
@@ -6720,6 +6806,9 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Alusta üksikmängu"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Aktiveerimiseks varjud, nad vajavad OpenGL draiver."
+
 #, fuzzy
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Lülita kiirus sisse"
@@ -6730,5 +6819,8 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "Jah"
 
+#~ msgid "You died."
+#~ msgstr "Said otsa."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index a2f5ed31f93a45a18eefa6217581dcce0e7f94be..2cd9b4b74d3e99e83f6ee830839ae7252353198e 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-02-23 15:50+0000\n"
 "Last-Translator: Osoitz <oelkoro@gmail.com>\n"
 "Language-Team: Basque <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -65,11 +65,6 @@ msgstr "Birsortu"
 msgid "You died"
 msgstr "Hil zara"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Hil zara"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -101,6 +96,10 @@ msgstr ""
 msgid "OK"
 msgstr "Ados"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Errore bat gertatu da Lua script batean:"
@@ -304,6 +303,13 @@ msgstr "$1 Instalatu"
 msgid "Install missing dependencies"
 msgstr "Falta diren mendekotasunak instalatu"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"Instalakuntza: \"$1\" sustengu gabeko fitxategi formatua edo hondatutako "
+"fitxategia"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -635,7 +641,8 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Iraunkortasuna"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -746,16 +753,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Mod instalakuntza: ezinezkoa $1 mod-entzako karpeta izen egokia aurkitzea"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Instalakuntza: \"$1\" sustengu gabeko fitxategi formatua edo hondatutako "
-"fitxategia"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instalakuntza: fitxategia: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Ezinezkoa baliozko mod edo mod pakete bat aurkitzea"
@@ -1127,10 +1124,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1163,7 +1156,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1192,7 +1185,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1233,14 +1226,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Sormen modua: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Kaltea: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1262,6 +1247,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Errore bat gertatu da:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1270,6 +1265,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1278,6 +1289,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1290,6 +1305,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1298,6 +1317,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1321,6 +1344,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Bezeroa sortzen..."
@@ -1513,6 +1541,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1847,6 +1890,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Huts egin du $1 deskargatzean"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Pasahitzak ez datoz bat!"
@@ -2042,7 +2094,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2249,6 +2302,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2516,6 +2573,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Agindua"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2549,7 +2611,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2568,6 +2630,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2643,6 +2711,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Agindua tekla"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2734,7 +2818,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2811,8 +2895,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2933,6 +3017,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2979,7 +3067,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3008,13 +3103,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr "Ahalbidetu jokalariek kaltea jasotzea eta hiltzea."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3103,6 +3191,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3288,11 +3382,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3301,6 +3399,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3360,10 +3469,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3418,7 +3523,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3850,7 +3955,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3935,7 +4040,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Joystick mota"
 
 #: src/settings_translation_file.cpp
@@ -4796,7 +4901,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5089,7 +5194,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5100,6 +5205,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5221,7 +5330,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5245,11 +5354,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5272,17 +5383,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5386,9 +5493,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5681,26 +5788,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5791,7 +5890,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5896,6 +5995,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6006,7 +6113,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6025,7 +6132,7 @@ msgstr "Eduki biltegiaren URL helbidea"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "Joystick mota"
 
 #: src/settings_translation_file.cpp
@@ -6096,7 +6203,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6192,6 +6299,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6262,7 +6373,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6445,6 +6556,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6466,7 +6581,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6474,14 +6589,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6609,24 +6717,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6640,6 +6730,12 @@ msgstr "cURL-en denbora muga"
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Sormen modua: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Kaltea: "
+
 #~ msgid "Back"
 #~ msgstr "Atzera"
 
@@ -6652,6 +6748,9 @@ msgstr ""
 #~ msgid "Downloading and installing $1, please wait..."
 #~ msgstr "$1 deskargatu eta instalatzen, itxaron mesedez..."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instalakuntza: fitxategia: \"$1\""
+
 #~ msgid "Ok"
 #~ msgstr "Ados"
 
@@ -6661,5 +6760,9 @@ msgstr ""
 #~ msgid "Special key"
 #~ msgstr "Berezia tekla"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Hil zara"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index e125804171dd881793f15385a1e0d66106f88260..3639a255ca847a0671a0b4021f4f87987e1ed941 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-04-10 15:49+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-09-19 07:38+0000\n"
 "Last-Translator: Markus Mikkonen <markus.mikkonen@outlook.com>\n"
 "Language-Team: Finnish <https://hosted.weblate.org/projects/minetest/"
 "minetest/fi/>\n"
@@ -17,44 +17,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.6-dev\n"
+"X-Generator: Weblate 4.9-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Tyhjennä keskustelujono"
 
 #: builtin/client/chatcommands.lua
 msgid "Empty command."
-msgstr ""
+msgstr "Tyhjä komento."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Takaisin päävalikkoon"
+msgstr "Poistu päävalikkoon"
 
 #: builtin/client/chatcommands.lua
 msgid "Invalid command: "
-msgstr ""
+msgstr "Virheellinen komento: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Annettu komento: "
 
 #: builtin/client/chatcommands.lua
 msgid "List online players"
-msgstr ""
+msgstr "Listaa verkkopelaajat"
 
 #: builtin/client/chatcommands.lua
 msgid "Online players: "
-msgstr ""
+msgstr "Verkkopelaajat: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Keskustelujono on nyt tyhjä."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Palvelin on poistanut komennon käytöstä."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,31 +63,28 @@ msgstr "Synny uudelleen"
 msgid "You died"
 msgstr "Kuolit"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Kuolit"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
-msgstr ""
+msgstr "Käytettävissä olevat komennot:"
 
 #: builtin/common/chatcommands.lua
 msgid "Available commands: "
-msgstr ""
+msgstr "Käytettävissä olevat komennot: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Komento ei ole käytettävissä: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Ohjeita komentojen käyttöön"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Käytä '.help <cmd>' saadaksesi lisätietoja komennosta, tai '.help all' "
+"listataksesi kaiken."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
@@ -98,6 +94,11 @@ msgstr ""
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Komento ei ole käytettävissä: "
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua-skriptissä tapahtui virhe:"
@@ -196,7 +197,7 @@ msgstr "Pelin kuvausta ei ole annettu."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No hard dependencies"
-msgstr ""
+msgstr "Ei kovia riippuvuuksia"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No modpack description provided."
@@ -225,7 +226,7 @@ msgstr "käytössä"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "\"$1\" already exists. Would you like to overwrite it?"
-msgstr ""
+msgstr "\"$1\" on jo olemassa. Haluatko korvata sen?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
@@ -263,11 +264,11 @@ msgstr "Asennettu jo"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Back to Main Menu"
-msgstr "Takaisin päävalikkoon"
+msgstr "Palaa päävalikkoon"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Base Game:"
-msgstr ""
+msgstr "Peruspeli:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
@@ -288,7 +289,7 @@ msgstr "Pelit"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Install"
-msgstr "Asenna"
+msgstr "Asentaa"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Install $1"
@@ -298,6 +299,10 @@ msgstr "Asenna $1"
 msgid "Install missing dependencies"
 msgstr "Asenna puuttuvat riippuvuudet"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -305,7 +310,7 @@ msgstr "Modit"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No packages could be retrieved"
-msgstr ""
+msgstr "Paketteja ei voitu noutaa"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No results"
@@ -317,7 +322,7 @@ msgstr "Ei päivityksiä"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Not found"
-msgstr ""
+msgstr "Ei löytynyt"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
@@ -329,7 +334,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "Jonotettu"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Texture packs"
@@ -349,7 +354,7 @@ msgstr "Päivitä kaikki [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "Katso lisätietoja verkkoselaimessa"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
@@ -437,7 +442,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Lakes"
-msgstr ""
+msgstr "Järvet"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Low humidity and high heat causes shallow or dry rivers"
@@ -449,11 +454,11 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen flags"
-msgstr ""
+msgstr "Mapgen-valitsimet"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mapgen-specific flags"
-msgstr ""
+msgstr "Mapgen-spesifit valitsimet"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mountains"
@@ -481,7 +486,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Rivers"
-msgstr ""
+msgstr "Joet"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Sea level rivers"
@@ -536,7 +541,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Warning: The Development Test is meant for developers."
-msgstr ""
+msgstr "Varoitus: Development Test on tarkoitettu kehittäjille."
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "World name"
@@ -558,11 +563,11 @@ msgstr "Poista"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: failed to delete \"$1\""
-msgstr ""
+msgstr "pkgmgr: kohteen \"$1\" poistaminen epäonnistui"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: invalid path \"$1\""
-msgstr ""
+msgstr "pkgmgr: virheellinen polku \"$1\""
 
 #: builtin/mainmenu/dlg_delete_world.lua
 msgid "Delete World \"$1\"?"
@@ -574,7 +579,7 @@ msgstr "Hyväksy"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid "Rename Modpack:"
-msgstr ""
+msgstr "Nimeä modipaketti uudelleen:"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid ""
@@ -592,7 +597,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "< Back to Settings page"
-msgstr "< Takaisin asetussivulle"
+msgstr "< Palaa asetussivulle"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Browse"
@@ -623,20 +628,20 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid integer."
-msgstr ""
+msgstr "Anna kelvollinen kokonaisuluku."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid number."
-msgstr ""
+msgstr "Anna kelvollinen numero."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Restore Default"
-msgstr ""
+msgstr "Palauta oletus"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Scale"
@@ -660,11 +665,11 @@ msgstr "Näytä tekniset nimet"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "The value must be at least $1."
-msgstr ""
+msgstr "Arvon tulee olla vähintään $1."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "The value must not be larger than $1."
-msgstr ""
+msgstr "Arvo ei saa olla suurempi kuin $1."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "X"
@@ -719,7 +724,7 @@ msgstr "$1 (Käytössä)"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "$1 mods"
-msgstr ""
+msgstr "$1 modia"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Failed to install $1 to $2"
@@ -733,14 +738,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -767,7 +764,7 @@ msgstr "Ladataan..."
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Public server list is disabled"
-msgstr ""
+msgstr "Julkinen palvelinlista on pois käytöstä"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
@@ -777,7 +774,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Tietoja"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
@@ -793,7 +790,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Open User Data Directory"
-msgstr ""
+msgstr "Avaa käyttäjätietohakemisto"
 
 #: builtin/mainmenu/tab_about.lua
 msgid ""
@@ -811,11 +808,11 @@ msgstr ""
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Browse online content"
-msgstr ""
+msgstr "Selaa sisältöä verkossa"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Content"
-msgstr ""
+msgstr "Sisältö"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Disable Texture Pack"
@@ -823,7 +820,7 @@ msgstr "Poista tekstuuripaketti käytöstä"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Information:"
-msgstr ""
+msgstr "Tietoja:"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Installed Packages:"
@@ -851,11 +848,11 @@ msgstr "Käytä tekstuuripakettia"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Announce Server"
-msgstr ""
+msgstr "Ilmoita palvelin"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Bind Address"
-msgstr ""
+msgstr "Sido osoite"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Creative Mode"
@@ -863,23 +860,23 @@ msgstr "Luova tila"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Enable Damage"
-msgstr ""
+msgstr "Ota vahinko käyttöön"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Game"
-msgstr ""
+msgstr "Isännöi peli"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Server"
-msgstr ""
+msgstr "Isännöi palvelin"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Install games from ContentDB"
-msgstr ""
+msgstr "Asenna pelejä ContentDB:stä"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "Nimi"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
@@ -887,11 +884,11 @@ msgstr "Uusi"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "No world created or selected!"
-msgstr ""
+msgstr "Maailmaa ei ole luotu tai valittu!"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Password"
-msgstr ""
+msgstr "Salasana"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
@@ -903,7 +900,7 @@ msgstr "Portti"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select Mods"
-msgstr ""
+msgstr "Valitse modit"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select World:"
@@ -911,20 +908,19 @@ msgstr "Valitse maailma:"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Server Port"
-msgstr ""
+msgstr "Palvelimen portti"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Start Game"
-msgstr ""
+msgstr "Aloita peli"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "Osoite / Portti"
+msgstr "Osoite"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
-msgstr ""
+msgstr "Tyhjennä"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Connect"
@@ -937,20 +933,19 @@ msgstr "Luova tila"
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
 msgid "Damage / PvP"
-msgstr ""
+msgstr "Vahinko / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr ""
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Suosikki"
+msgstr "Suosikit"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Palvelimet eivät ole yhteensopivat"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -962,15 +957,15 @@ msgstr "Viive"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Public Servers"
-msgstr ""
+msgstr "Julkiset palvelimet"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Päivitä"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Server Description"
-msgstr ""
+msgstr "Palvelimen kuvaus"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -978,7 +973,7 @@ msgstr "2x"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "3D Clouds"
-msgstr ""
+msgstr "3D-pilvet"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "4x"
@@ -994,19 +989,19 @@ msgstr "Kaikki asetukset"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Antialiasing:"
-msgstr ""
+msgstr "Reunanpehmennys:"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Autosave Screen Size"
-msgstr ""
+msgstr "Tallenna näytön koko automaattisesti"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Bilinear Filter"
-msgstr ""
+msgstr "Bilineaarinen suodatus"
 
 #: builtin/mainmenu/tab_settings.lua src/client/game.cpp
 msgid "Change Keys"
-msgstr ""
+msgstr "Näppäinasetukset"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Connected Glass"
@@ -1014,11 +1009,11 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "Dynaamiset varjot"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dynaamiset varjot: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1046,7 +1041,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "No Filter"
-msgstr ""
+msgstr "Ei suodatinta"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "No Mipmap"
@@ -1070,7 +1065,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Water"
-msgstr ""
+msgstr "Läpinäkymätön vesi"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Particles"
@@ -1078,7 +1073,7 @@ msgstr "Partikkelit"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Screen:"
-msgstr ""
+msgstr "Näyttö:"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Settings"
@@ -1086,15 +1081,15 @@ msgstr "Asetukset"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Shaders"
-msgstr ""
+msgstr "Varjostimet"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (experimental)"
-msgstr ""
+msgstr "Varjostimet (kokeellinen)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
-msgstr ""
+msgstr "Varjostimet (ei käytettävissä)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Simple Leaves"
@@ -1102,15 +1097,11 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Smooth Lighting"
-msgstr ""
+msgstr "Tasainen valaistus"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Texturing:"
-msgstr ""
-
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
+msgstr "Teksturointi:"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
@@ -1144,13 +1135,13 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
-msgstr ""
+msgstr "Yhteys aikakatkaistiin."
 
 #: src/client/client.cpp
 msgid "Done!"
-msgstr ""
+msgstr "Valmis!"
 
 #: src/client/client.cpp
 msgid "Initializing nodes"
@@ -1166,14 +1157,14 @@ msgstr "Ladataan tekstuureja..."
 
 #: src/client/client.cpp
 msgid "Rebuilding shaders..."
-msgstr ""
+msgstr "Rakennetaan uudelleen varjostimia..."
 
 #: src/client/clientlauncher.cpp
 msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1182,7 +1173,7 @@ msgstr ""
 
 #: src/client/clientlauncher.cpp
 msgid "Main Menu"
-msgstr ""
+msgstr "Päävalikko"
 
 #: src/client/clientlauncher.cpp
 msgid "No world selected and no address provided. Nothing to do."
@@ -1190,11 +1181,11 @@ msgstr ""
 
 #: src/client/clientlauncher.cpp
 msgid "Player name too long."
-msgstr ""
+msgstr "Pelaajan nimi on liian pitkä."
 
 #: src/client/clientlauncher.cpp
 msgid "Please choose a name!"
-msgstr ""
+msgstr "Valitse nimi!"
 
 #: src/client/clientlauncher.cpp
 msgid "Provided password file failed to open: "
@@ -1212,35 +1203,37 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "- Address: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
+msgstr "- Osoite: "
 
 #: src/client/game.cpp
 msgid "- Mode: "
-msgstr ""
+msgstr "- Tila: "
 
 #: src/client/game.cpp
 msgid "- Port: "
-msgstr ""
+msgstr "- Portti: "
 
 #: src/client/game.cpp
 msgid "- Public: "
-msgstr ""
+msgstr "- Julkinen: "
 
 #. ~ PvP = Player versus Player
 #: src/client/game.cpp
 msgid "- PvP: "
-msgstr ""
+msgstr "- PvP: "
 
 #: src/client/game.cpp
 msgid "- Server Name: "
+msgstr "- Palvelimen nimi: "
+
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Tapahtui virhe:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
 msgstr ""
 
 #: src/client/game.cpp
@@ -1251,6 +1244,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1260,9 +1269,13 @@ msgid "Camera update enabled"
 msgstr ""
 
 #: src/client/game.cpp
-msgid "Change Password"
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Change Password"
+msgstr "Vaihda salasana"
+
 #: src/client/game.cpp
 msgid "Cinematic mode disabled"
 msgstr ""
@@ -1271,17 +1284,25 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
 
 #: src/client/game.cpp
 msgid "Connecting to server..."
+msgstr "Yhdistetään palvelimeen..."
+
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
 msgstr ""
 
 #: src/client/game.cpp
 msgid "Continue"
-msgstr ""
+msgstr "Jatka"
 
 #: src/client/game.cpp
 #, c-format
@@ -1303,12 +1324,17 @@ msgid ""
 msgstr ""
 
 #: src/client/game.cpp
-msgid "Creating client..."
+#, c-format
+msgid "Couldn't resolve address: %s"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Creating client..."
+msgstr "Luodaan asiakasta..."
+
 #: src/client/game.cpp
 msgid "Creating server..."
-msgstr ""
+msgstr "Luodaan palvelinta..."
 
 #: src/client/game.cpp
 msgid "Debug info and profiler graph hidden"
@@ -1348,11 +1374,11 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Exit to Menu"
-msgstr ""
+msgstr "Poistu valikkoon"
 
 #: src/client/game.cpp
 msgid "Exit to OS"
-msgstr ""
+msgstr "Poistu käyttöjärjestelmään"
 
 #: src/client/game.cpp
 msgid "Fast mode disabled"
@@ -1368,11 +1394,11 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Fly mode disabled"
-msgstr ""
+msgstr "Lentotila pois käytöstä"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled"
-msgstr ""
+msgstr "Lentotila käytössä"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled (note: no 'fly' privilege)"
@@ -1380,19 +1406,19 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Fog disabled"
-msgstr ""
+msgstr "Sumu pois käytöstä"
 
 #: src/client/game.cpp
 msgid "Fog enabled"
-msgstr ""
+msgstr "Sumu käytössä"
 
 #: src/client/game.cpp
 msgid "Game info:"
-msgstr ""
+msgstr "Pelin tiedot:"
 
 #: src/client/game.cpp
 msgid "Game paused"
-msgstr ""
+msgstr "Peli keskeytetty"
 
 #: src/client/game.cpp
 msgid "Hosting server"
@@ -1440,11 +1466,11 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Off"
-msgstr ""
+msgstr "Pois"
 
 #: src/client/game.cpp
 msgid "On"
-msgstr ""
+msgstr "Päällä"
 
 #: src/client/game.cpp
 msgid "Pitch move mode disabled"
@@ -1460,27 +1486,27 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Remote server"
-msgstr ""
+msgstr "Etäpalvelin"
 
 #: src/client/game.cpp
 msgid "Resolving address..."
-msgstr ""
+msgstr "Selvitetään osoitetta..."
 
 #: src/client/game.cpp
 msgid "Shutting down..."
-msgstr ""
+msgstr "Sammutetaan..."
 
 #: src/client/game.cpp
 msgid "Singleplayer"
-msgstr ""
+msgstr "Yksinpeli"
 
 #: src/client/game.cpp
 msgid "Sound Volume"
-msgstr ""
+msgstr "Äänenvoimakkuus"
 
 #: src/client/game.cpp
 msgid "Sound muted"
-msgstr ""
+msgstr "Ääni mykistetty"
 
 #: src/client/game.cpp
 msgid "Sound system is disabled"
@@ -1492,6 +1518,21 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Sound unmuted"
+msgstr "Ääni palautettu"
+
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
 msgstr ""
 
 #: src/client/game.cpp
@@ -1528,7 +1569,7 @@ msgstr ""
 
 #: src/client/gameui.cpp
 msgid "Chat hidden"
-msgstr ""
+msgstr "Keskustelu piilotettu"
 
 #: src/client/gameui.cpp
 msgid "Chat shown"
@@ -1828,13 +1869,22 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Epäonnistui ladata $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
-msgstr ""
+msgstr "Salasanat eivät täsmää!"
 
 #: src/gui/guiConfirmRegistration.cpp
 msgid "Register and Join"
-msgstr ""
+msgstr "Rekisteröidy ja liity"
 
 #: src/gui/guiConfirmRegistration.cpp
 #, c-format
@@ -1845,6 +1895,10 @@ msgid ""
 "Please retype your password and click 'Register and Join' to confirm account "
 "creation, or click 'Cancel' to abort."
 msgstr ""
+"Olet aikeissa liittyä tälle palvelimelle nimellä \"%s\" ensimmäistä kertaa.\n"
+"Jos jatkat, uusi tili kirjautumistietojen kera luodaan tälle palvelimelle.\n"
+"Kirjoita salasana ja napsauta \"Rekisteröidy ja liity\" vahvistaaksesi tilin "
+"luomisen, tai napsauta \"Peruuta\" lopettaaksesi."
 
 #: src/gui/guiFormSpecMenu.cpp
 msgid "Proceed"
@@ -1860,7 +1914,7 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
 msgid "Automatic jumping"
-msgstr ""
+msgstr "Hypi automaattisesti"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
@@ -1868,7 +1922,7 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
-msgstr ""
+msgstr "Taakse"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
@@ -1876,19 +1930,19 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
-msgstr ""
+msgstr "Vaihda kameraa"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Chat"
-msgstr ""
+msgstr "Keskustelu"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Command"
-msgstr ""
+msgstr "Komento"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Console"
-msgstr ""
+msgstr "Konsoli"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. range"
@@ -1908,7 +1962,7 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Forward"
-msgstr ""
+msgstr "Eteen"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. range"
@@ -1920,11 +1974,11 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inventory"
-msgstr ""
+msgstr "Inventaario"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Jump"
-msgstr ""
+msgstr "Hyppää"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Key already in use"
@@ -1933,10 +1987,12 @@ msgstr ""
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
 msgstr ""
+"Näppäimistöasetukset. (Jos tämä valikko rikkoutuu, poista asioita minetest."
+"conf-tiedostosta)"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Local command"
-msgstr ""
+msgstr "Paikallinen komento"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Mute"
@@ -1956,11 +2012,11 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
 msgid "Screenshot"
-msgstr ""
+msgstr "Kuvakaappaus"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Sneak"
-msgstr ""
+msgstr "Hiivi"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle HUD"
@@ -2004,27 +2060,28 @@ msgstr ""
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Confirm Password"
-msgstr ""
+msgstr "Vahvista salasana"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "New Password"
-msgstr ""
+msgstr "Uusi salasana"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Old Password"
-msgstr ""
+msgstr "Vanha salasana"
 
 #: src/gui/guiVolumeChange.cpp
 msgid "Exit"
-msgstr ""
+msgstr "Poistu"
 
 #: src/gui/guiVolumeChange.cpp
 msgid "Muted"
-msgstr ""
+msgstr "Mykistetty"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr ""
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Äänenvoimakkuus: "
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2105,11 +2162,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "3D clouds"
-msgstr ""
+msgstr "3D-pilvet"
 
 #: src/settings_translation_file.cpp
 msgid "3D mode"
-msgstr ""
+msgstr "3D-tila"
 
 #: src/settings_translation_file.cpp
 msgid "3D mode parallax strength"
@@ -2230,6 +2287,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2242,7 +2303,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
-msgstr ""
+msgstr "Lisäasetukset"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2336,7 +2397,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Autosave screen size"
-msgstr ""
+msgstr "Tallenna näytön koko automaattisesti"
 
 #: src/settings_translation_file.cpp
 msgid "Autoscaling mode"
@@ -2496,6 +2557,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Komento"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2529,7 +2595,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2549,12 +2615,18 @@ msgid "Clean transparent textures"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Client"
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Client"
+msgstr "Asiakas"
+
 #: src/settings_translation_file.cpp
 msgid "Client and Server"
-msgstr ""
+msgstr "Asiakas ja palvelin"
 
 #: src/settings_translation_file.cpp
 msgid "Client modding"
@@ -2578,7 +2650,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Clouds"
-msgstr ""
+msgstr "Pilvet"
 
 #: src/settings_translation_file.cpp
 msgid "Clouds are a client side effect."
@@ -2623,6 +2695,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2714,7 +2802,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2791,8 +2879,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2910,6 +2998,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2956,13 +3048,20 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
-msgstr ""
+msgstr "Käytä konsoli-ikkunaa"
 
 #: src/settings_translation_file.cpp
 msgid "Enable creative mode for all players"
@@ -2984,13 +3083,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3075,6 +3167,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3259,11 +3357,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3272,6 +3374,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3331,10 +3444,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3357,11 +3466,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Full screen"
-msgstr ""
+msgstr "Koko näyttö"
 
 #: src/settings_translation_file.cpp
 msgid "Fullscreen mode."
-msgstr ""
+msgstr "Koko näytön tila."
 
 #: src/settings_translation_file.cpp
 msgid "GUI scaling"
@@ -3383,7 +3492,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3400,7 +3509,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Graphics"
-msgstr ""
+msgstr "Grafiikka"
 
 #: src/settings_translation_file.cpp
 msgid "Gravity"
@@ -3416,7 +3525,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "HTTP mods"
-msgstr ""
+msgstr "HTTP-modit"
 
 #: src/settings_translation_file.cpp
 msgid "HUD scale factor"
@@ -3490,7 +3599,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Homepage of server, to be displayed in the serverlist."
-msgstr ""
+msgstr "Palvelimen sivusto, näytetään palvelinlistauksessa."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3681,11 +3790,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "IPv6"
-msgstr ""
+msgstr "IPv6"
 
 #: src/settings_translation_file.cpp
 msgid "IPv6 server"
-msgstr ""
+msgstr "IPv6-palvelin"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3786,7 +3895,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "In-Game"
-msgstr ""
+msgstr "Pelinsisäinen"
 
 #: src/settings_translation_file.cpp
 msgid "In-game chat console background alpha (opaqueness, between 0 and 255)."
@@ -3815,7 +3924,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3899,7 +4008,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4481,7 +4590,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Language"
-msgstr ""
+msgstr "Kieli"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave depth"
@@ -4728,7 +4837,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4833,7 +4942,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum FPS"
-msgstr ""
+msgstr "FPS enintään"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum FPS when the window is not focused, or when the game is paused."
@@ -4962,11 +5071,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
-msgstr ""
+msgstr "Käyttäjiä enintään"
 
 #: src/settings_translation_file.cpp
 msgid "Menus"
-msgstr ""
+msgstr "Valikot"
 
 #: src/settings_translation_file.cpp
 msgid "Mesh cache"
@@ -5021,7 +5130,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5032,6 +5141,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5050,7 +5163,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Mouse sensitivity"
-msgstr ""
+msgstr "Hiiren herkkyys"
 
 #: src/settings_translation_file.cpp
 msgid "Mouse sensitivity multiplier."
@@ -5072,7 +5185,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Mute sound"
-msgstr ""
+msgstr "Mykistä ääni"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5100,7 +5213,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Network"
-msgstr ""
+msgstr "Verkko"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5110,7 +5223,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "New users need to input this password."
-msgstr ""
+msgstr "Uusien käyttäjien tulee syöttää tämä salasana."
 
 #: src/settings_translation_file.cpp
 msgid "Noclip"
@@ -5153,7 +5266,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5177,11 +5290,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5204,17 +5319,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5232,7 +5343,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Physics"
-msgstr ""
+msgstr "Fysiikka"
 
 #: src/settings_translation_file.cpp
 msgid "Pitch move key"
@@ -5258,7 +5369,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Player name"
-msgstr ""
+msgstr "Pelaajan nimi"
 
 #: src/settings_translation_file.cpp
 msgid "Player transfer distance"
@@ -5266,7 +5377,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Player versus player"
-msgstr ""
+msgstr "Pelaaja vastaan pelaaja"
 
 #: src/settings_translation_file.cpp
 msgid "Poisson filtering"
@@ -5317,9 +5428,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5480,23 +5591,23 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Screen height"
-msgstr ""
+msgstr "Näytön korkeus"
 
 #: src/settings_translation_file.cpp
 msgid "Screen width"
-msgstr ""
+msgstr "Näytön leveys"
 
 #: src/settings_translation_file.cpp
 msgid "Screenshot folder"
-msgstr ""
+msgstr "Kuvakaappausten kansio"
 
 #: src/settings_translation_file.cpp
 msgid "Screenshot format"
-msgstr ""
+msgstr "Kuvakaappausten muoto"
 
 #: src/settings_translation_file.cpp
 msgid "Screenshot quality"
-msgstr ""
+msgstr "Kuvakaappausten laatu"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5519,11 +5630,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Security"
-msgstr ""
+msgstr "Turvallisuus"
 
 #: src/settings_translation_file.cpp
 msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
-msgstr ""
+msgstr "Lue https://www.sqlite.org/pragma.html#pragma_synchronous"
 
 #: src/settings_translation_file.cpp
 msgid "Selection box border color (R,G,B)."
@@ -5562,27 +5673,27 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Server / Singleplayer"
-msgstr ""
+msgstr "Palvelin / yksinpeli"
 
 #: src/settings_translation_file.cpp
 msgid "Server URL"
-msgstr ""
+msgstr "Palvelimen URL"
 
 #: src/settings_translation_file.cpp
 msgid "Server address"
-msgstr ""
+msgstr "Palvelimen osoite"
 
 #: src/settings_translation_file.cpp
 msgid "Server description"
-msgstr ""
+msgstr "Palvelimen kuvaus"
 
 #: src/settings_translation_file.cpp
 msgid "Server name"
-msgstr ""
+msgstr "Palvelimen nimi"
 
 #: src/settings_translation_file.cpp
 msgid "Server port"
-msgstr ""
+msgstr "Palvelimen portti"
 
 #: src/settings_translation_file.cpp
 msgid "Server side occlusion culling"
@@ -5612,26 +5723,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5722,7 +5825,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5798,7 +5901,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sneaking speed"
-msgstr ""
+msgstr "Hiiviskelyn nopeus"
 
 #: src/settings_translation_file.cpp
 msgid "Sneaking speed, in nodes per second."
@@ -5810,7 +5913,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
-msgstr ""
+msgstr "Ääni"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5827,6 +5930,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5885,7 +5996,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Synchronous SQLite"
-msgstr ""
+msgstr "Synkroninen SQLite"
 
 #: src/settings_translation_file.cpp
 msgid "Temperature variation for biomes."
@@ -5937,7 +6048,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5955,7 +6066,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6024,7 +6135,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6117,6 +6228,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6134,7 +6249,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Trusted mods"
-msgstr ""
+msgstr "Luotetut modit"
 
 #: src/settings_translation_file.cpp
 msgid "URL to the server list displayed in the Multiplayer Tab."
@@ -6187,7 +6302,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6273,7 +6388,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Video driver"
-msgstr ""
+msgstr "Videoajuri"
 
 #: src/settings_translation_file.cpp
 msgid "View bobbing factor"
@@ -6328,7 +6443,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Walking speed"
-msgstr ""
+msgstr "Kävelyn nopeus"
 
 #: src/settings_translation_file.cpp
 msgid "Walking, flying and climbing speed in fast mode, in nodes per second."
@@ -6370,6 +6485,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6391,7 +6510,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6399,14 +6518,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6532,24 +6644,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6562,8 +6656,26 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Luova tila: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Vahinko: "
+
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType-fontit"
+
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Asenna: tiedosto: \"$1\""
+
 #~ msgid "Name / Password"
 #~ msgstr "Nimi / Salasana"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Varjostimien käyttäminen vaatii, että käytössä on OpenGL-ajuri."
+
+#~ msgid "You died."
+#~ msgstr "Kuolit."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 785c161a548a47e20b0d05731938800534464986..ef7f889867b2d44bdb6edc3f1e13092ccf1e6405 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -60,10 +60,6 @@ msgstr ""
 msgid "You died"
 msgstr ""
 
-#: builtin/client/death_formspec.lua
-msgid "You died."
-msgstr ""
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -93,6 +89,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr ""
@@ -291,6 +291,10 @@ msgstr ""
 msgid "Install missing dependencies"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -616,7 +620,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -726,14 +730,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1097,10 +1093,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1133,7 +1125,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1162,7 +1154,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1203,14 +1195,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1232,6 +1216,15 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1240,6 +1233,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1248,6 +1257,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1260,6 +1273,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1268,6 +1285,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1291,6 +1312,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1483,6 +1509,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1817,6 +1858,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2012,7 +2061,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2219,6 +2269,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2485,6 +2539,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2518,7 +2576,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2537,6 +2595,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2612,6 +2676,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2703,7 +2783,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2780,8 +2860,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2899,6 +2979,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2945,7 +3029,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2973,13 +3064,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3064,6 +3148,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3248,11 +3338,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3261,6 +3355,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3320,10 +3425,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3372,7 +3473,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3804,7 +3905,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3888,7 +3989,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4717,7 +4818,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5010,7 +5111,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5021,6 +5122,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5142,7 +5247,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5166,11 +5271,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5193,17 +5300,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5306,9 +5409,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5601,26 +5704,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5711,7 +5806,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5816,6 +5911,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5926,7 +6029,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5944,7 +6047,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6013,7 +6116,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6106,6 +6209,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6176,7 +6283,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6359,6 +6466,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6380,7 +6491,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6388,14 +6499,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6521,24 +6625,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
index aa0ffd1588d826c8d32701f8f32f0f0877769d3a..55105200401552a8bbfcce390effefc80b033f71 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: French (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-06-02 19:33+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-29 00:17+0000\n"
 "Last-Translator: waxtatect <piero@live.ie>\n"
 "Language-Team: French <https://hosted.weblate.org/projects/minetest/minetest/"
 "fr/>\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Taille maximale de la file de sortie de message du tchat"
+msgstr "Effacer la file de sortie de message du tchat"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Commandes de tchat"
+msgstr "Commande vide."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Menu principal"
+msgstr "Quitter vers le menu principal"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Commande locale"
+msgstr "Commande invalide : "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Commande émise : "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Solo"
+msgstr "Liste des joueurs en ligne"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Solo"
+msgstr "Joueurs en ligne : "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "La file de sortie de message du tchat est maintenant vide."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Cette commande est désactivée par le serveur."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,41 @@ msgstr "Réapparaître"
 msgid "You died"
 msgstr "Vous êtes mort"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Vous êtes mort"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Commande locale"
+msgstr "Commandes disponibles :"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Commande locale"
+msgstr "Commandes disponibles : "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Commande non disponible : "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Obtenir de l'aide pour les commandes"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Utiliser « .help <cmd> » pour obtenir plus d'informations, ou « .help all » "
+"pour tout lister."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "< aucun disponible >"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Une erreur est survenue dans un script Lua :"
@@ -207,7 +200,7 @@ msgstr "Aucune description fournie pour le pack de mods."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No optional dependencies"
-msgstr "Pas de dépendances facultatives"
+msgstr "Pas de dépendances optionnelles"
 
 #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua
 msgid "Optional dependencies:"
@@ -216,7 +209,7 @@ msgstr "Dépendances optionnelles :"
 #: builtin/mainmenu/dlg_config_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp
 msgid "Save"
-msgstr "Enregistrer"
+msgstr "Sauvegarder"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "World:"
@@ -303,6 +296,10 @@ msgstr "Installer $1"
 msgid "Install missing dependencies"
 msgstr "Installer les dépendances manquantes"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Installation : type de fichier non supporté ou archive endommagée"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -346,7 +343,7 @@ msgstr "Désinstaller"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update"
-msgstr "Mise à jour"
+msgstr "Mettre à jour"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
@@ -370,7 +367,7 @@ msgstr "Refroidissement en altitude"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Altitude dry"
-msgstr "Faible humidité d'altitude"
+msgstr "Faible humidité en altitude"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Biome blending"
@@ -398,11 +395,11 @@ msgstr "Décorations"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download a game, such as Minetest Game, from minetest.net"
-msgstr "Téléchargez un jeu comme Minetest Game depuis minetest.net"
+msgstr "Télécharger un jeu comme Minetest Game depuis minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download one from minetest.net"
-msgstr "Téléchargez-en un depuis minetest.net"
+msgstr "Téléchargeen un depuis minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Dungeons"
@@ -414,11 +411,11 @@ msgstr "Terrain plat"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floating landmasses in the sky"
-msgstr "Îles volantes"
+msgstr "Masses de terrains flottants dans le ciel"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floatlands (experimental)"
-msgstr "Îles volantes (expérimental)"
+msgstr "Terrains flottants (expérimental)"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Game"
@@ -426,7 +423,7 @@ msgstr "Jeu"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Generate non-fractal terrain: Oceans and underground"
-msgstr "Générer un terrain non fractal : océans et souterrain"
+msgstr "Générer un terrain non fractal : océans et souterrains"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Hills"
@@ -446,7 +443,8 @@ msgstr "Lacs"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Low humidity and high heat causes shallow or dry rivers"
-msgstr "L'air sec et chaud réduit le niveau d'eau ou assèche les rivières"
+msgstr ""
+"Humidité basse et chaleur élevée rendent les rivières peu profondes ou sèches"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen"
@@ -470,7 +468,7 @@ msgstr "Coulée de boue"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Network of tunnels and caves"
-msgstr "Réseau souterrain"
+msgstr "Réseau de tunnels et de grottes"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "No game selected"
@@ -478,11 +476,11 @@ msgstr "Aucun jeu sélectionné"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces heat with altitude"
-msgstr "Réduire la température avec l'altitude"
+msgstr "Réduit la chaleur avec l'altitude"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces humidity with altitude"
-msgstr "Réduire l'humidité avec l'altitude"
+msgstr "Réduit l'humidité avec l'altitude"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Rivers"
@@ -490,7 +488,7 @@ msgstr "Rivières"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Sea level rivers"
-msgstr "Rivière au niveau de mer"
+msgstr "Rivières au niveau de la mer"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -506,8 +504,8 @@ msgid ""
 "Structures appearing on the terrain (no effect on trees and jungle grass "
 "created by v6)"
 msgstr ""
-"Structures apparaissantes sur le sol (sans effets sur la création d'arbre et "
-"de jungle par v6)"
+"Structures apparaissant sur le sol (sans effet sur la création d'arbres et "
+"d'herbes de la jungle par v6)"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Structures appearing on the terrain, typically trees and plants"
@@ -521,11 +519,11 @@ msgstr "Tempéré, désertique"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle"
-msgstr "Tempéré, désertique, tropical"
+msgstr "Tempéré, désertique, jungle"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr "Tempéré, désertique, tropical, de toundra, de taïga"
+msgstr "Tempéré, désertique, jungle, toundra, taïga"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Terrain surface erosion"
@@ -533,7 +531,7 @@ msgstr "Érosion du sol"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
-msgstr "Arbres et végétation de jungle"
+msgstr "Arbres et herbes de la jungle"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Vary river depth"
@@ -541,11 +539,11 @@ msgstr "Varier la profondeur fluviale"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Very large caverns deep in the underground"
-msgstr "Très grande cavernes profondes"
+msgstr "Très grandes cavernes profondes souterraines"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Warning: The Development Test is meant for developers."
-msgstr "Avertissement : le jeu minimal est fait pour les développeurs."
+msgstr "Avertissement : le jeu minimal est fait pour les développeurs."
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "World name"
@@ -567,11 +565,11 @@ msgstr "Supprimer"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: failed to delete \"$1\""
-msgstr "Le gestionnaire de mods n'a pas pu supprimer « $1 »"
+msgstr "Gestionnaire de mods : échec de la suppression de « $1 »"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: invalid path \"$1\""
-msgstr "Gestionnaire de mods : chemin de mod invalide « $1 »"
+msgstr "Gestionnaire de mods : chemin invalide de « $1 »"
 
 #: builtin/mainmenu/dlg_delete_world.lua
 msgid "Delete World \"$1\"?"
@@ -590,12 +588,12 @@ msgid ""
 "This modpack has an explicit name given in its modpack.conf which will "
 "override any renaming here."
 msgstr ""
-"Ce pack de mods a un nom explicitement donné dans son fichier modpack.conf ; "
-"il écrasera tout renommage effectué ici."
+"Ce pack de mods a un nom explicitement donné dans son fichier modpack.conf "
+"qui remplacera tout renommage effectué ici."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "(No description of setting given)"
-msgstr "(Aucune description donnée de l'option)"
+msgstr "(Aucune description du paramètre donnée)"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "2D Noise"
@@ -631,11 +629,11 @@ msgstr "Octaves"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Offset"
-msgstr "Décallage"
+msgstr "Décalage"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
-msgstr "Persistence"
+msgid "Persistence"
+msgstr "Persistance"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid integer."
@@ -651,7 +649,7 @@ msgstr "Réinitialiser"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Scale"
-msgstr "Echelle"
+msgstr "Échelle"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua
 msgid "Search"
@@ -659,7 +657,7 @@ msgstr "Rechercher"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Select directory"
-msgstr "Choisissez un répertoire"
+msgstr "Choisir un répertoire"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Select file"
@@ -722,7 +720,7 @@ msgstr "Paramètres par défaut"
 #. main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "eased"
-msgstr "lissé"
+msgstr "Lissé"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "$1 (Enabled)"
@@ -738,24 +736,13 @@ msgstr "Échec de l'installation de $1 vers $2"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Install Mod: Unable to find real mod name for: $1"
-msgstr ""
-"Installation d'un mod : impossible de trouver le vrai nom du mod pour : $1"
+msgstr "Installer mod : impossible de trouver le nom réel du mod pour : $1"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
-"Installation un mod : impossible de trouver un nom de dossier valide pour le "
-"pack de mods $1"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Installation d'un mod : type de fichier non supporté « $1 » ou archive "
-"endommagée"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Installation : fichier : « $1 »"
+"Installer mod : impossible de trouver un nom de dossier valide pour le pack "
+"de mods $1"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
@@ -763,11 +750,11 @@ msgstr "Impossible de trouver un mod ou un pack de mods valide"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to install a $1 as a texture pack"
-msgstr "Échec de l'installation de $1 comme pack de textures"
+msgstr "Impossible d'installer un $1 comme un pack de textures"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to install a game as a $1"
-msgstr "Échec de l'installation du jeu comme un $1"
+msgstr "Impossible d'installer un jeu comme un $1"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to install a mod as a $1"
@@ -788,21 +775,20 @@ msgstr "La liste des serveurs publics est désactivée"
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
 msgstr ""
-"Essayez de rechargez la liste des serveurs publics et vérifiez votre "
-"connexion Internet."
+"Essayer de réactiver la liste des serveurs et vérifier votre connexion "
+"Internet."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "À propos"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Contributeurs actifs"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Portée des objets actifs envoyés"
+msgstr "Moteur de rendu actif :"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -817,9 +803,9 @@ msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
-"Ouvre le répertoire qui contient les mondes fournis par les utilisateurs, "
-"les jeux, les mods,\n"
-"et des paquets de textures dans un gestionnaire de fichiers."
+"Ouvre le répertoire qui contient les mondes, les jeux, les mods et les packs "
+"de textures\n"
+"fournis par l'utilisateur dans un gestionnaire de fichiers/explorateur."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
@@ -891,7 +877,7 @@ msgstr "Héberger une partie"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Server"
-msgstr "Héberger un serveur"
+msgstr "Héberger le serveur"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Install games from ContentDB"
@@ -938,9 +924,8 @@ msgid "Start Game"
 msgstr "Démarrer"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adresse : "
+msgstr "Adresse"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -956,22 +941,20 @@ msgstr "Mode créatif"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Dégâts"
+msgstr "Dégâts / JcJ"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Supprimer favori"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favori"
+msgstr "Favoris"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Serveurs incompatibles"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -982,16 +965,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Annoncer le serveur"
+msgstr "Serveurs publics"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Actualiser"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Description du serveur"
 
@@ -1036,13 +1017,12 @@ msgid "Connected Glass"
 msgstr "Verre unifié"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Ombre de la police"
+msgstr "Ombres dynamiques"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Ombres dynamiques : "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1050,19 +1030,19 @@ msgstr "Feuilles détaillées"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Élevées"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Basses"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Moyennes"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
-msgstr "MIP mapping"
+msgstr "MIP map"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap + Aniso. Filter"
@@ -1106,7 +1086,7 @@ msgstr "Écran :"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Settings"
-msgstr "Réglages"
+msgstr "Paramètres"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Shaders"
@@ -1132,11 +1112,6 @@ msgstr "Lumière douce"
 msgid "Texturing:"
 msgstr "Texturisation :"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-"Pour activer les textures nuancées, le pilote OpenGL doit être utilisé."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Mappage tonal"
@@ -1151,11 +1126,11 @@ msgstr "Filtrage trilinéaire"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Très élevées"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Très basses"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1169,7 +1144,7 @@ msgstr "Liquides ondulants"
 msgid "Waving Plants"
 msgstr "Plantes ondulantes"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Connexion perdue."
 
@@ -1191,19 +1166,19 @@ msgstr "Chargement des textures…"
 
 #: src/client/client.cpp
 msgid "Rebuilding shaders..."
-msgstr "Reconstruction des textures nuancées…"
+msgstr "Reconstruction des shaders…"
 
 #: src/client/clientlauncher.cpp
 msgid "Connection error (timed out?)"
 msgstr "Erreur de connexion (perte de connexion ?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Impossible de trouver ou charger le jeu \""
+msgid "Could not find or load game"
+msgstr "Impossible de trouver ou charger le jeu : "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
-msgstr "gamespec invalide."
+msgstr "Jeu spécifié invalide."
 
 #: src/client/clientlauncher.cpp
 msgid "Main Menu"
@@ -1235,40 +1210,41 @@ msgid ""
 "Check debug.txt for details."
 msgstr ""
 "\n"
-"Voir debug.txt pour plus d'informations."
+"Voir « debug.txt » pour plus d'informations."
 
 #: src/client/game.cpp
 msgid "- Address: "
-msgstr "- Adresse : "
-
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Mode créatif : "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Dégâts : "
+msgstr "– Adresse : "
 
 #: src/client/game.cpp
 msgid "- Mode: "
-msgstr "Mode : "
+msgstr "– Mode : "
 
 #: src/client/game.cpp
 msgid "- Port: "
-msgstr "Port : "
+msgstr "– Port : "
 
 #: src/client/game.cpp
 msgid "- Public: "
-msgstr "Public : "
+msgstr "– Public : "
 
 #. ~ PvP = Player versus Player
 #: src/client/game.cpp
 msgid "- PvP: "
-msgstr "JcJ : "
+msgstr "– JcJ : "
 
 #: src/client/game.cpp
 msgid "- Server Name: "
-msgstr "- Nom du serveur : "
+msgstr "– Nom du serveur : "
+
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Une erreur de sérialisation est survenue :"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Accès refusé. Raison : %s"
 
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
@@ -1278,6 +1254,22 @@ msgstr "Marche automatique désactivée"
 msgid "Automatic forward enabled"
 msgstr "Marche automatique activée"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Limites des blocs cachées"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Limites des blocs affichées pour tous les blocs"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Limites des blocs affichées pour le bloc actuel"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Limites des blocs affichées pour les blocs voisins"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Mise à jour de la caméra désactivée"
@@ -1286,9 +1278,15 @@ msgstr "Mise à jour de la caméra désactivée"
 msgid "Camera update enabled"
 msgstr "Mise à jour de la caméra activée"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+"Impossible d'afficher les limites des blocs (nécessite le privilège "
+"« basic_debug »)"
+
 #: src/client/game.cpp
 msgid "Change Password"
-msgstr "Changer de mot de passe"
+msgstr "Changer le mot de passe"
 
 #: src/client/game.cpp
 msgid "Cinematic mode disabled"
@@ -1298,6 +1296,10 @@ msgstr "Mode cinématique désactivé"
 msgid "Cinematic mode enabled"
 msgstr "Mode cinématique activé"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Client déconnecté"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Les scripts côté client sont désactivés"
@@ -1306,6 +1308,10 @@ msgstr "Les scripts côté client sont désactivés"
 msgid "Connecting to server..."
 msgstr "Connexion au serveur…"
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "La connexion a échoué pour une raison inconnue"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Continuer"
@@ -1328,21 +1334,26 @@ msgid ""
 "- Mouse wheel: select item\n"
 "- %s: chat\n"
 msgstr ""
-"Contrôles : \n"
-"– %s : avancer\n"
-"– %s : reculer\n"
-"– %s : à gauche\n"
-"– %s : à droite\n"
-"– %s : sauter/grimper\n"
-"– %s : creuser/actionner\n"
-"– %s : placer/utiliser\n"
-"– %s : marcher lentement/descendre\n"
-"– %s : lâcher un objet\n"
-"– %s : inventaire\n"
-"– Souris : tourner/regarder\n"
-"– Molette souris : sélectionner un objet\n"
+"Contrôles :\n"
+"– %s : avancer\n"
+"– %s : reculer\n"
+"– %s : à gauche\n"
+"– %s : à droite\n"
+"– %s : sauter/grimper\n"
+"– %s : creuser/actionner\n"
+"– %s : placer/utiliser\n"
+"– %s : marcher lentement/descendre\n"
+"– %s : lâcher un objet\n"
+"– %s : inventaire\n"
+"– Souris : tourner/regarder\n"
+"– Molette souris : sélectionner un objet\n"
 "– %s : tchat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Impossible de résoudre l'adresse : %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Création du client…"
@@ -1353,15 +1364,15 @@ msgstr "Création du serveur…"
 
 #: src/client/game.cpp
 msgid "Debug info and profiler graph hidden"
-msgstr "Informations de debogage et graphique de profil cachés"
+msgstr "Informations de débogage et graphique du profileur cachés"
 
 #: src/client/game.cpp
 msgid "Debug info shown"
-msgstr "Infos de débogage affichées"
+msgstr "Informations de débogage affichées"
 
 #: src/client/game.cpp
 msgid "Debug info, profiler graph, and wireframe hidden"
-msgstr "Informations de debogage, graphique de profil et fils de fer cachés"
+msgstr "Informations de débogage, graphique du profileur et fils de fer cachés"
 
 #: src/client/game.cpp
 msgid ""
@@ -1378,15 +1389,15 @@ msgid ""
 "- touch&drag, tap 2nd finger\n"
 " --> place single item to slot\n"
 msgstr ""
-"Touches par défaut : \n"
-"Sans menu visible : \n"
-"– un seul appui : touche d'activation\n"
-"– double-appui : placement / utilisation\n"
-"– Glissement du doigt : regarder autour\n"
-"Menu / Inventaire visible : \n"
-"– double-appui (en dehors) : fermeture\n"
-"– objet(s) dans l'inventaire : déplacement\n"
-"– appui, glissement et appui : pose d'un seul item par emplacement\n"
+"Touches par défaut :\n"
+"Sans menu visible :\n"
+"– un seul appui : touche d'activation\n"
+"– double-appui : placement / utilisation\n"
+"– Glissement du doigt : regarder autour\n"
+"Menu / Inventaire visible :\n"
+"– double-appui (en dehors) : fermeture\n"
+"– objets dans l'inventaire : déplacement\n"
+"– appui, glissement et appui : pose d'un seul objet par emplacement\n"
 
 #: src/client/game.cpp
 msgid "Disabled unlimited viewing range"
@@ -1414,7 +1425,7 @@ msgstr "Vitesse en mode rapide activée"
 
 #: src/client/game.cpp
 msgid "Fast mode enabled (note: no 'fast' privilege)"
-msgstr "Vitesse en mode rapide activée (note : pas de privilège « fast »)"
+msgstr "Vitesse en mode rapide activée (note : pas de privilège « fast »)"
 
 #: src/client/game.cpp
 msgid "Fly mode disabled"
@@ -1426,7 +1437,7 @@ msgstr "Mode vol activé"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled (note: no 'fly' privilege)"
-msgstr "Mode vol activé (note : pas de privilège « fly »)"
+msgstr "Mode vol activé (note : pas de privilège « fly »)"
 
 #: src/client/game.cpp
 msgid "Fog disabled"
@@ -1446,7 +1457,7 @@ msgstr "Jeu en pause"
 
 #: src/client/game.cpp
 msgid "Hosting server"
-msgstr "Héberger un serveur"
+msgstr "Serveur hôte"
 
 #: src/client/game.cpp
 msgid "Item definitions..."
@@ -1469,9 +1480,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Mini-carte actuellement désactivée par un jeu ou un mod"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Solo"
+msgstr "Multijoueur"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1483,7 +1493,7 @@ msgstr "Collisions désactivées"
 
 #: src/client/game.cpp
 msgid "Noclip mode enabled (note: no 'noclip' privilege)"
-msgstr "Collisions activées (note : pas de privilège « noclip »)"
+msgstr "Collisions activées (note : pas de privilège « noclip »)"
 
 #: src/client/game.cpp
 msgid "Node definitions..."
@@ -1507,7 +1517,7 @@ msgstr "Mode de mouvement à direction libre activé"
 
 #: src/client/game.cpp
 msgid "Profiler graph shown"
-msgstr "Graphique de profil affiché"
+msgstr "Graphique du profileur affiché"
 
 #: src/client/game.cpp
 msgid "Remote server"
@@ -1535,7 +1545,7 @@ msgstr "Son coupé"
 
 #: src/client/game.cpp
 msgid "Sound system is disabled"
-msgstr "L'audio système est désactivé"
+msgstr "Le système audio est désactivé"
 
 #: src/client/game.cpp
 msgid "Sound system is not supported on this build"
@@ -1545,6 +1555,21 @@ msgstr "Cette compilation ne gère pas l'audio du système"
 msgid "Sound unmuted"
 msgstr "Son rétabli"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Le serveur utilise probablement une version différente de %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Impossible de se connecter à %s car IPv6 est désactivé"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Impossible d’écouter sur %s car IPv6 est désactivé"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1553,17 +1578,17 @@ msgstr "Distance de vue réglée sur %d"
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range is at maximum: %d"
-msgstr "Distance de vue maximale : %d"
+msgstr "Distance de vue maximale : %d"
 
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range is at minimum: %d"
-msgstr "Distance de vue minimale : %d"
+msgstr "Distance de vue minimale : %d"
 
 #: src/client/game.cpp
 #, c-format
 msgid "Volume changed to %d%%"
-msgstr "Volume réglé sur %d %%"
+msgstr "Volume réglé sur %d %%"
 
 #: src/client/game.cpp
 msgid "Wireframe shown"
@@ -1672,7 +1697,7 @@ msgstr "Gauche"
 
 #: src/client/keycode.cpp
 msgid "Left Button"
-msgstr "Bouton gauche"
+msgstr "Clic gauche"
 
 #: src/client/keycode.cpp
 msgid "Left Control"
@@ -1697,7 +1722,7 @@ msgstr "Menu"
 
 #: src/client/keycode.cpp
 msgid "Middle Button"
-msgstr "Bouton du milieu"
+msgstr "Clic central"
 
 #: src/client/keycode.cpp
 msgid "Num Lock"
@@ -1798,7 +1823,7 @@ msgstr "Droite"
 
 #: src/client/keycode.cpp
 msgid "Right Button"
-msgstr "Bouton droit"
+msgstr "Clic droit"
 
 #: src/client/keycode.cpp
 msgid "Right Control"
@@ -1879,6 +1904,14 @@ msgstr "Mini-carte en mode surface, zoom ×%d"
 msgid "Minimap in texture mode"
 msgstr "Mini-carte en mode texture"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Échec de l'ouverture de la page Web"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Ouverture de la page web"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Les mots de passe ne correspondent pas !"
@@ -1901,7 +1934,7 @@ msgstr ""
 "Si vous continuez, un nouveau compte utilisant vos identifiants sera créé "
 "sur ce serveur.\n"
 "Veuillez retaper votre mot de passe et cliquer sur « S'enregistrer et "
-"rejoindre » pour confirmer la création de votre compte, ou cliquez sur "
+"rejoindre » pour confirmer la création de votre compte, ou cliquer sur "
 "« Annuler »."
 
 #: src/gui/guiFormSpecMenu.cpp
@@ -1909,9 +1942,8 @@ msgid "Proceed"
 msgstr "Procéder"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "« Spécial » = descendre"
+msgstr "« Aux1 » = descendre"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1923,7 +1955,7 @@ msgstr "Sauts automatiques"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1931,7 +1963,7 @@ msgstr "Reculer"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Limites des blocs"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2055,7 +2087,7 @@ msgstr "Mouvement vertical"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "press key"
-msgstr "Appuyez sur une touche"
+msgstr "Appuyer sur une touche"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Change"
@@ -2082,8 +2114,9 @@ msgid "Muted"
 msgstr "Muet"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Volume du son : "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Volume du son : %d %%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2108,14 +2141,13 @@ msgstr ""
 "principal."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Utiliser la manette virtuelle pour déclencher le bouton « aux ».\n"
-"Si activé, la manette virtuelle va également appuyer sur le bouton « aux » "
+"(Android) Utiliser la manette virtuelle pour déclencher le bouton « Aux1 ».\n"
+"Si activé, la manette virtuelle va également appuyer sur le bouton « Aux1 » "
 "lorsqu'en dehors du cercle principal."
 
 #: src/settings_translation_file.cpp
@@ -2150,18 +2182,17 @@ msgid ""
 "Default is for a vertically-squashed shape suitable for\n"
 "an island, set all 3 numbers equal for the raw shape."
 msgstr ""
-"(Échelle (X,Y,Z) de fractales, en nœuds.\n"
-"La taille des fractales sera 2 à 3 fais plus grande en réalité.\n"
-"Ces nombres peuvent être très grands, les fractales de devant\n"
-"pas être impérativement contenues dans le monde.\n"
-"Augmentez-les pour « zoomer » dans les détails de la fractale.\n"
-"Le réglage par défaut correspond à un forme écrasée verticalement, "
-"appropriée pour\n"
-"un île, rendez les 3 nombres égaux pour la forme de base."
+"Échelle (X,Y,Z) de la fractale en nœuds.\n"
+"La taille réelle de la fractale sera 2 à 3 fois plus grande.\n"
+"Ces nombres peuvent être très grands, la fractale n'a pas à être contenue "
+"dans le monde. Les augmenter pour « zoomer » dans les détails de la "
+"fractale.\n"
+"Le valeur par défaut est pour une forme verticalement écrasée convenant pour "
+"une île, définir les 3 nombres égaux pour la forme brute."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of ridged mountains."
-msgstr "Bruit 2D controllant la forme et taille des montagnes crantées."
+msgstr "Bruit 2D contrôlant la forme et taille des montagnes crantées."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of rolling hills."
@@ -2209,7 +2240,7 @@ msgid ""
 "Also defines structure of floatland mountain terrain."
 msgstr ""
 "Bruit 3D définissant la structure et la hauteur des montagnes.\n"
-"Définit également la structure des montagnes flottantes."
+"Définit également la structure de terrain flottant type montagne."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2218,10 +2249,11 @@ msgid ""
 "to be adjusted, as floatland tapering functions best when this noise has\n"
 "a value range of approximately -2.0 to 2.0."
 msgstr ""
-"Bruit 3D pour la structures des îles volantes.\n"
+"Bruit 3D pour la structures des terrains flottants.\n"
 "Si la valeur par défaut est changée, le bruit « d'échelle » (0,7 par défaut) "
-"doit peut-être être ajustée, parce que l'effilage des îles volantes "
-"fonctionne le mieux quand ce bruit est environ entre -2 et 2."
+"peut demander à être ajustée, comme l'effilage des terrains flottants "
+"fonctionne mieux quand le bruit à une valeur approximativement comprise "
+"entre -2,0 et 2,0."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining structure of river canyon walls."
@@ -2238,7 +2270,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "3D noise that determines number of dungeons per mapchunk."
-msgstr "Bruit 3D qui détermine le nombre de donjons par mapchunk."
+msgstr "Bruit 3D qui détermine le nombre de donjons par tranche de carte."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2254,15 +2286,15 @@ msgid ""
 "Note that the interlaced mode requires shaders to be enabled."
 msgstr ""
 "Support 3D.\n"
-"Actuellement supporté : \n"
-"– aucun : pas de sortie 3D.\n"
-"– anaglyphe : couleur 3D bleu turquoise/violet.\n"
-"– entrelacé : polarisation basée sur des lignes avec support de l'écran.\n"
-"– horizontal : partage haut/bas de l'écran.\n"
-"– vertical : séparation côte à côte de l'écran.\n"
-"– vue mixte : 3D binoculaire.\n"
-"– pageflip : 3D basé sur quadbuffer.\n"
-"Notez que le mode entrelacé nécessite que les shaders soient activés."
+"Actuellement supporté :\n"
+"– aucun : pas de sortie 3D.\n"
+"– anaglyphe : couleur 3D bleu turquoise/violet.\n"
+"– entrelacé : polarisation basée sur des lignes avec support de l'écran.\n"
+"– horizontal : partage haut/bas de l'écran.\n"
+"– vertical : séparation côte à côte de l'écran.\n"
+"– vue mixte : 3D binoculaire.\n"
+"– « pageflip » : 3D basé sur « quadbuffer ».\n"
+"Noter que le mode entrelacé nécessite que les shaders soient activés."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2276,7 +2308,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server crashes."
 msgstr ""
-"Un message qui sera affiché à tous les joueurs quand le serveur s'interrompt."
+"Un message qui sera affiché à tous les joueurs quand le serveur plante."
 
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server shuts down."
@@ -2313,7 +2345,7 @@ msgstr "intervalle de gestion des blocs actifs"
 
 #: src/settings_translation_file.cpp
 msgid "Active block range"
-msgstr "Portée des mapblocks actifs"
+msgstr "Portée des blocs actifs"
 
 #: src/settings_translation_file.cpp
 msgid "Active object send range"
@@ -2327,8 +2359,8 @@ msgid ""
 msgstr ""
 "Adresse où se connecter.\n"
 "Laisser vide pour démarrer un serveur local.\n"
-"Notez que le champ de l'adresse dans le menu principal passe outre ce "
-"réglage."
+"Noter que le champ de l'adresse dans le menu principal passe outre ce "
+"paramètre."
 
 #: src/settings_translation_file.cpp
 msgid "Adds particles when digging a node."
@@ -2339,8 +2371,14 @@ msgid ""
 "Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k "
 "screens."
 msgstr ""
-"Ajuster la résolution de votre écran (non-X11 / Android seulement) ex. pour "
-"les écrans 4k."
+"Ajuste la configuration des PPP à votre écran (non X11 / Android seulement), "
+"par exemple pour les écrans 4k."
+
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Ajuste la densité d'affichage détectée, utilisée pour la mise à l'échelle "
+"des éléments de l'interface utilisateur."
 
 #: src/settings_translation_file.cpp
 #, c-format
@@ -2351,12 +2389,12 @@ msgid ""
 "Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n"
 "to be sure) creates a solid floatland layer."
 msgstr ""
-"Règle la densité de la couche des îles volantes.\n"
+"Règle la densité de la couche de terrain flottant.\n"
 "Augmenter la valeur pour augmenter la densité. Peut être positive ou "
 "négative.\n"
-"Valeur = 0,0 : 50 % du volume est île volante.\n"
+"Valeur = 0,0 : 50 % du volume est terrain flottant.\n"
 "Valeur = 2,0 (peut être plus élevée selon « mgv7_np_floatland », toujours "
-"vérifier pour être sûr) crée une couche d'île volante solide."
+"vérifier pour être sûr) créée une couche de terrain flottant solide."
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
@@ -2374,8 +2412,8 @@ msgstr ""
 "Des valeurs plus élevées rendent les niveaux de lumière moyens et inférieurs "
 "plus lumineux.\n"
 "La valeur « 1,0 » laisse la courbe de lumière intacte.\n"
-"Cela n'a d'effet significatif que sur la lumière du jour et les\n"
-"la lumière, et elle a très peu d'effet sur la lumière naturelle de la nuit."
+"Cela n'a un effet significatif que sur la lumière du jour et la lumière "
+"artificielle, elle a très peu d'effet sur la lumière naturelle nocturne."
 
 #: src/settings_translation_file.cpp
 msgid "Always fly and fast"
@@ -2383,7 +2421,7 @@ msgstr "Toujours voler et être rapide"
 
 #: src/settings_translation_file.cpp
 msgid "Ambient occlusion gamma"
-msgstr "Occlusion gamma ambiente"
+msgstr "Occlusion gamma ambiante"
 
 #: src/settings_translation_file.cpp
 msgid "Amount of messages a player may send per 10 seconds."
@@ -2403,7 +2441,7 @@ msgstr "Annoncer le serveur"
 
 #: src/settings_translation_file.cpp
 msgid "Announce to this serverlist."
-msgstr "Annoncer le serveur publiquement."
+msgstr "Annoncer à cette liste de serveurs."
 
 #: src/settings_translation_file.cpp
 msgid "Append item name"
@@ -2411,7 +2449,7 @@ msgstr "Ajouter un nom d'objet"
 
 #: src/settings_translation_file.cpp
 msgid "Append item name to tooltip."
-msgstr "Ajouter un nom d'objet à l'info-bulle."
+msgstr "Ajouter un nom d'objet à l'infobulle."
 
 #: src/settings_translation_file.cpp
 msgid "Apple trees noise"
@@ -2453,13 +2491,13 @@ msgstr ""
 "mais peut provoquer l'apparition de problèmes de rendu visibles (certains "
 "blocs ne seront pas affichés sous l'eau ou dans les cavernes, ou parfois sur "
 "terre).\n"
-"Une valeur supérieure à max_block_send_distance désactive cette "
+"Une valeur supérieure à « max_block_send_distance » désactive cette "
 "optimisation.\n"
-"Définie en mapblocks (16 nœuds)."
+"Établie en blocs de carte (16 nœuds)."
 
 #: src/settings_translation_file.cpp
 msgid "Automatic forward key"
-msgstr "Touche de marche automatique"
+msgstr "Touche marche automatique"
 
 #: src/settings_translation_file.cpp
 msgid "Automatically jump up single-node obstacles."
@@ -2467,7 +2505,7 @@ msgstr "Saute automatiquement sur les obstacles d'un bloc de haut."
 
 #: src/settings_translation_file.cpp
 msgid "Automatically report to the serverlist."
-msgstr "Déclarer automatiquement le serveur à la liste des serveurs publics."
+msgstr "Déclarer automatiquement le serveur à la liste des serveurs."
 
 #: src/settings_translation_file.cpp
 msgid "Autosave screen size"
@@ -2478,18 +2516,16 @@ msgid "Autoscaling mode"
 msgstr "Mode d'agrandissement automatique"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Sauter"
+msgstr "Touche Aux1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Touche spéciale pour monter/descendre"
+msgstr "Touche Aux1 pour monter/descendre"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
-msgstr "Reculer"
+msgstr "Touche reculer"
 
 #: src/settings_translation_file.cpp
 msgid "Base ground level"
@@ -2509,11 +2545,11 @@ msgstr "Privilèges de base"
 
 #: src/settings_translation_file.cpp
 msgid "Beach noise"
-msgstr "Bruit pour les plages"
+msgstr "Bruit des plages"
 
 #: src/settings_translation_file.cpp
 msgid "Beach noise threshold"
-msgstr "Seuil de bruit pour les plages"
+msgstr "Seuil de bruit des plages"
 
 #: src/settings_translation_file.cpp
 msgid "Bilinear filtering"
@@ -2541,15 +2577,15 @@ msgstr "Chemin de la police en gras et en italique"
 
 #: src/settings_translation_file.cpp
 msgid "Bold and italic monospace font path"
-msgstr "Chemin de la police Monospace en gras et en italique"
+msgstr "Chemin de la police monospace en gras et en italique"
 
 #: src/settings_translation_file.cpp
 msgid "Bold font path"
-msgstr "Chemin du fichier de police en gras"
+msgstr "Chemin de la police en gras"
 
 #: src/settings_translation_file.cpp
 msgid "Bold monospace font path"
-msgstr "Chemin de la police Monospace en gras"
+msgstr "Chemin de la police monospace en gras"
 
 #: src/settings_translation_file.cpp
 msgid "Build inside player"
@@ -2566,7 +2602,7 @@ msgid ""
 "Increasing can reduce artifacting on weaker GPUs.\n"
 "0.1 = Default, 0.25 = Good value for weaker tablets."
 msgstr ""
-"Distance de la caméra 'près du plan de coupure' dans les nœuds, entre 0 et "
+"Distance de la caméra « près du plan de coupure » dans les nœuds, entre 0 et "
 "0,25\n"
 "Ne fonctionne que sur les plateformes GLES. La plupart des utilisateurs "
 "n’auront pas besoin de changer cela.\n"
@@ -2583,47 +2619,47 @@ msgstr "Lissage du mouvement de la caméra en mode cinématique"
 
 #: src/settings_translation_file.cpp
 msgid "Camera update toggle key"
-msgstr "Touche de mise à jour de la caméra"
+msgstr "Touche mise à jour de la caméra"
 
 #: src/settings_translation_file.cpp
 msgid "Cave noise"
-msgstr "Bruit des caves"
+msgstr "Bruit de grottes"
 
 #: src/settings_translation_file.cpp
 msgid "Cave noise #1"
-msgstr "Bruit de cave nº 1"
+msgstr "Bruit de grottes nº 1"
 
 #: src/settings_translation_file.cpp
 msgid "Cave noise #2"
-msgstr "Bruit de grotte nº 2"
+msgstr "Bruit de grottes nº 2"
 
 #: src/settings_translation_file.cpp
 msgid "Cave width"
-msgstr "Largeur de la grotte"
+msgstr "Largeur des grottes"
 
 #: src/settings_translation_file.cpp
 msgid "Cave1 noise"
-msgstr "Bruit des cave nº 1"
+msgstr "Bruit de grottes nº 1"
 
 #: src/settings_translation_file.cpp
 msgid "Cave2 noise"
-msgstr "Bruit des caves nº 2"
+msgstr "Bruit de grottes nº 2"
 
 #: src/settings_translation_file.cpp
 msgid "Cavern limit"
-msgstr "Limites des cavernes"
+msgstr "Limite des cavernes"
 
 #: src/settings_translation_file.cpp
 msgid "Cavern noise"
-msgstr "Bruit des caves"
+msgstr "Bruit de cavernes"
 
 #: src/settings_translation_file.cpp
 msgid "Cavern taper"
-msgstr "Caillou de caverne"
+msgstr "Conicité des cavernes"
 
 #: src/settings_translation_file.cpp
 msgid "Cavern threshold"
-msgstr "Limite des cavernes"
+msgstr "Seuil des cavernes"
 
 #: src/settings_translation_file.cpp
 msgid "Cavern upper limit"
@@ -2639,17 +2675,20 @@ msgstr ""
 "maximale."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Seuil de messages de discussion avant déconnexion forcée"
+msgstr "Seuil de message du temps de commande du tchat"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Commandes de tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
-msgstr "Taille de police du tchat"
+msgstr "Taille de la police du tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat key"
-msgstr "Tchatter"
+msgstr "Touche tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat log level"
@@ -2657,11 +2696,11 @@ msgstr "Niveau du journal du tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message count limit"
-msgstr "Limite du nombre de message de discussion"
+msgstr "Limite du nombre de messages de tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message format"
-msgstr "Format du message de tchat"
+msgstr "Format de message du tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message kick threshold"
@@ -2673,15 +2712,15 @@ msgstr "Longueur maximale d'un message de tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat toggle key"
-msgstr "Afficher le tchat"
+msgstr "Touche afficher le tchat"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Commandes de tchat"
+msgid "Chat weblinks"
+msgstr "Liens web de tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
-msgstr "Taille des chunks"
+msgstr "Taille des tranches"
 
 #: src/settings_translation_file.cpp
 msgid "Cinematic mode"
@@ -2689,12 +2728,20 @@ msgstr "Mode cinématique"
 
 #: src/settings_translation_file.cpp
 msgid "Cinematic mode key"
-msgstr "Mode cinématique"
+msgstr "Touche mode cinématique"
 
 #: src/settings_translation_file.cpp
 msgid "Clean transparent textures"
 msgstr "Textures transparentes filtrées"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Liens web cliquables (molette de la souris ou ctrl+clic gauche) activés dans "
+"la sortie de la console de tchat."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Client"
@@ -2740,9 +2787,8 @@ msgid "Colored fog"
 msgstr "Brouillard coloré"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Brouillard coloré"
+msgstr "Ombres colorées"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2758,7 +2804,7 @@ msgstr ""
 "« nonfree » peut être utilisé pour cacher les paquets non libres, comme "
 "défini par la Free Software Foundation.\n"
 "Vous pouvez aussi spécifier des classifications de contenu.\n"
-"Ces drapeaux sont indépendants des versions de Minetest, consultez la liste "
+"Ces drapeaux sont indépendants des versions de Minetest, consulter la liste "
 "complète à l'adresse https://content.minetest.net/help/content_flags/"
 
 #: src/settings_translation_file.cpp
@@ -2782,7 +2828,33 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Command key"
-msgstr "Commande"
+msgstr "Touche commande"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Niveau de compression à utiliser lors de la sauvegarde des blocs de carte "
+"sur le disque.\n"
+"-1 - utilise le niveau de compression par défaut\n"
+"0 - compression minimale, le plus rapide\n"
+"9 - meilleure compression, le plus lent"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Niveau de compression à utiliser lors de l'envoi des blocs de carte au "
+"client.\n"
+"-1 - utilise le niveau de compression par défaut\n"
+"0 - compression minimale, le plus rapide\n"
+"9 - meilleure compression, le plus lent"
 
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
@@ -2830,7 +2902,7 @@ msgid ""
 "Press the autoforward key again or the backwards movement to disable."
 msgstr ""
 "Mouvement continu en avant, activé par la touche d'avance automatique.\n"
-"Appuyez à nouveau sur la touche d'avance automatique ou de recul pour le "
+"Appuyer à nouveau sur la touche d'avance automatique ou de recul pour le "
 "désactiver."
 
 #: src/settings_translation_file.cpp
@@ -2844,7 +2916,7 @@ msgid ""
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
 "Contrôle la durée complet du cycle jour/nuit.\n"
-"Exemples : \n"
+"Exemples :\n"
 "72 = 20 minutes, 360 = 4 minutes, 1 = 24 heures, 0 = jour/nuit/n'importe "
 "quoi éternellement."
 
@@ -2867,9 +2939,9 @@ msgid ""
 "intensive noise calculations."
 msgstr ""
 "Contrôle la largeur des tunnels, une valeur plus faible crée des tunnels "
-"plus large.\n"
-"Valeur >= 10,0 désactive complètement la génération de tunnel et évite\n"
-"le calcul intensif de bruit."
+"plus larges.\n"
+"Valeur >= 10,0 désactive complètement la génération de tunnels et évite le "
+"calcul intensif de bruit."
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
@@ -2886,10 +2958,10 @@ msgstr "Opacité du réticule"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Opacité du réticule (entre 0 et 255).\n"
-"Contrôle également la couleur du réticule de l'objet"
+"Cela contrôle également la couleur du réticule de l'objet."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2913,7 +2985,7 @@ msgstr "Dégâts"
 
 #: src/settings_translation_file.cpp
 msgid "Debug info toggle key"
-msgstr "Infos de débogage"
+msgstr "Touche infos de débogage"
 
 #: src/settings_translation_file.cpp
 msgid "Debug log file size threshold"
@@ -2925,11 +2997,11 @@ msgstr "Niveau du journal de débogage"
 
 #: src/settings_translation_file.cpp
 msgid "Dec. volume key"
-msgstr "Touche pour diminuer le volume"
+msgstr "Touche réduire le volume"
 
 #: src/settings_translation_file.cpp
 msgid "Decrease this to increase liquid resistance to movement."
-msgstr "Diminuez ceci pour augmenter la résistance liquide au mouvement."
+msgstr "Réduire ceci pour augmenter la résistance liquide au mouvement."
 
 #: src/settings_translation_file.cpp
 msgid "Dedicated server step"
@@ -2969,10 +3041,13 @@ msgstr "Taille d’empilement par défaut"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Défini la qualité du filtrage des ombres. Cela simule l'effet d'ombres "
+"douces en appliquant un disque PCF ou Poisson mais utilise également plus de "
+"ressources."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3003,7 +3078,7 @@ msgstr "Définit la structure des canaux fluviaux à grande échelle."
 #: src/settings_translation_file.cpp
 msgid "Defines location and terrain of optional hills and lakes."
 msgstr ""
-"Définit l'emplacement et le terrain des collines facultatives et des lacs."
+"Définit l'emplacement et le terrain des collines et des lacs optionnels."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the base ground level."
@@ -3036,8 +3111,7 @@ msgid ""
 "Delay between mesh updates on the client in ms. Increasing this will slow\n"
 "down the rate of mesh updates, thus reducing jitter on slower clients."
 msgstr ""
-"Délai entre les mises à jour du maillage sur le client en ms. Augmenter "
-"ceci\n"
+"Délai entre les mises à jour du maillage sur le client en ms. Augmenter ceci "
 "ralentit le taux de mise à jour et réduit donc les tremblements sur les "
 "client lents."
 
@@ -3047,7 +3121,7 @@ msgstr "Retard dans les blocs envoyés après la construction"
 
 #: src/settings_translation_file.cpp
 msgid "Delay showing tooltips, stated in milliseconds."
-msgstr "Latence d'apparition des infobulles, établie en millisecondes."
+msgstr "Délai d'apparition des infobulles, établi en millisecondes."
 
 #: src/settings_translation_file.cpp
 msgid "Deprecated Lua API handling"
@@ -3059,34 +3133,36 @@ msgstr "Profondeur en-dessous de laquelle se trouvent les grandes cavernes."
 
 #: src/settings_translation_file.cpp
 msgid "Depth below which you'll find large caves."
-msgstr "Profondeur en-dessous duquel se trouvent de grandes caves."
+msgstr "Profondeur en-dessous duquel se trouvent de grandes grottes."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Description of server, to be displayed when players join and in the "
 "serverlist."
-msgstr "Description du serveur affichée sur la liste des serveurs."
+msgstr ""
+"Description du serveur affichée lorsque les joueurs se connectent et sur la "
+"liste des serveurs."
 
 #: src/settings_translation_file.cpp
 msgid "Desert noise threshold"
-msgstr "Limite de bruit pour le désert"
+msgstr "Seuil de bruit des déserts"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Deserts occur when np_biome exceeds this value.\n"
 "When the 'snowbiomes' flag is enabled, this is ignored."
 msgstr ""
-"Des déserts apparaissent lorsque np_biome dépasse cette valeur.\n"
+"Des déserts apparaissent lorsque « np_biome » dépasse cette valeur.\n"
 "Quand le drapeau « snowbiomes » est activé (avec le nouveau système de "
 "biomes), ce paramètre est ignoré."
 
 #: src/settings_translation_file.cpp
 msgid "Desynchronize block animation"
-msgstr "Désynchroniser les textures animées par mapblock"
+msgstr "Désynchroniser les animations de blocs"
 
 #: src/settings_translation_file.cpp
 msgid "Dig key"
-msgstr "Touche pour creuser"
+msgstr "Touche creuser"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3100,9 +3176,13 @@ msgstr "Désactiver l'anti-triche"
 msgid "Disallow empty passwords"
 msgstr "Refuser les mots de passe vides"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Facteur d'échelle de la densité d'affichage"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
-msgstr "Nom de domaine du serveur affichée sur la liste des serveurs publics."
+msgstr "Nom de domaine du serveur affichée sur la liste des serveurs."
 
 #: src/settings_translation_file.cpp
 msgid "Double tap jump for fly"
@@ -3110,11 +3190,11 @@ msgstr "Double-appui sur « saut » pour voler"
 
 #: src/settings_translation_file.cpp
 msgid "Double-tapping the jump key toggles fly mode."
-msgstr "Double-appui sur « saut » pour voler."
+msgstr "Double-appui sur la touche « saut » pour voler."
 
 #: src/settings_translation_file.cpp
 msgid "Drop item key"
-msgstr "Lâcher"
+msgstr "Touche lâcher un objet"
 
 #: src/settings_translation_file.cpp
 msgid "Dump the mapgen debug information."
@@ -3130,7 +3210,7 @@ msgstr "Minimum Y des donjons"
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon noise"
-msgstr "Bruit de donjon"
+msgstr "Bruit de donjons"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3150,9 +3230,22 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Active le filtrage par disque de Poisson.\n"
+"Si activé, utilise le disque de Poisson pour créer des « ombres douces ». "
+"Sinon, utilise le filtrage PCF."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Active les ombres colorées.\n"
+"Sur les nœuds vraiment transparents, projette des ombres colorées. Ceci est "
+"coûteux."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3178,13 +3271,6 @@ msgstr "Activer la sécurisation des mods"
 msgid "Enable players getting damage and dying."
 msgstr "Active les dégâts et la mort des joueurs."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3199,8 +3285,7 @@ msgid ""
 "Enable register confirmation when connecting to server.\n"
 "If disabled, new account will be registered automatically."
 msgstr ""
-"Active la confirmation d'enregistrement lorsque vous vous connectez à un "
-"serveur.\n"
+"Active la confirmation d'enregistrement lors de la connexion à un serveur.\n"
 "Si cette option est désactivée, le nouveau compte sera créé automatiquement."
 
 #: src/settings_translation_file.cpp
@@ -3233,7 +3318,7 @@ msgid ""
 msgstr ""
 "Activer l'usage d'un serveur de média distant (si pourvu par le serveur).\n"
 "Les serveurs de média distants offrent un moyen significativement plus "
-"rapide de télécharger des données média (ex. : textures) lors de la "
+"rapide de télécharger des données média (ex. : textures) lors de la "
 "connexion au serveur."
 
 #: src/settings_translation_file.cpp
@@ -3241,7 +3326,7 @@ msgid ""
 "Enable vertex buffer objects.\n"
 "This should greatly improve graphics performance."
 msgstr ""
-"Active les vertex buffer objects.\n"
+"Active les « vertex buffer objects ».\n"
 "Cela devrait grandement augmenter les performances graphiques."
 
 #: src/settings_translation_file.cpp
@@ -3250,7 +3335,7 @@ msgid ""
 "For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
 msgstr ""
 "Facteur de mouvement de bras.\n"
-"Par exemple : 0 = pas de mouvement, 1 = normal, 2 = double."
+"Par exemple : 0 = pas de mouvement, 1 = normal, 2 = double."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3259,8 +3344,8 @@ msgid ""
 "Needs enable_ipv6 to be enabled."
 msgstr ""
 "Active/désactive l'usage d'un serveur IPv6.\n"
-"Ignoré si bind_address est activé.\n"
-"A besoin de enable_ipv6 pour être activé."
+"Ignoré si « bind_address » est activé.\n"
+"A besoin de « enable_ipv6 » pour être activé."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3269,7 +3354,7 @@ msgid ""
 "appearance of high dynamic range images. Mid-range contrast is slightly\n"
 "enhanced, highlights and shadows are gradually compressed."
 msgstr ""
-"Active le mappage de tons filmique 'Uncharted 2' de Hable.\n"
+"Active le mappage de tons filmique « Uncharted 2 » de Hable.\n"
 "Simule la courbe des tons du film photographique, ce qui se rapproche de la "
 "l'apparition d'images à plage dynamique élevée. Le contraste de milieu de "
 "gamme est légèrement améliorées, les reflets et les ombres sont "
@@ -3299,9 +3384,18 @@ msgstr ""
 "commandes audio dans le jeu ne fonctionneront pas.\n"
 "La modification de ce paramètre nécessite un redémarrage."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+"Active les compromis qui réduisent la charge du CPU ou augmentent les "
+"performances de rendu au détriment de problèmes visuels mineurs qui n'ont "
+"pas d'impact sur la jouabilité du jeu."
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
-msgstr "Intervalle d'impression des données du moteur de profil"
+msgstr "Intervalle d'impression des données du moteur de profilage"
 
 #: src/settings_translation_file.cpp
 msgid "Entity methods"
@@ -3316,12 +3410,14 @@ msgid ""
 "Values < 1.0 (for example 0.25) create a more defined surface level with\n"
 "flatter lowlands, suitable for a solid floatland layer."
 msgstr ""
-"Exposant contrôlant la forme du bas des massifs volants.\n"
-"Une valeur égale à 1 donne une forme conique.\n"
-"Une valeur supérieure à 1 donne une longue base éfilée (concave),\n"
-"plus pour des îles volantes comme celles par défaut.\n"
-"Une valeur inférieure à 1 (disons 0,25) donne une surface bien\n"
-"définie en bas, plus pour une couche solide de massif volant."
+"Exposant de l'effilement des terrains flottants. Modifie le comportement de "
+"l'effilement.\n"
+"Une valeur égale à 1 créée un effilement uniforme et linéaire.\n"
+"Une valeur supérieure à 1 créée un effilement lisse adaptée pour les "
+"terrains flottants séparés par défaut.\n"
+"Une valeur inférieure à 1 (par exemple 0,25) créée une surface plus définie "
+"avec des terrains bas plus plats, adaptée pour une couche solide de terrain "
+"flottant."
 
 #: src/settings_translation_file.cpp
 msgid "FPS when unfocused or paused"
@@ -3341,11 +3437,11 @@ msgstr "Intensité du mouvement de tête en tombant"
 
 #: src/settings_translation_file.cpp
 msgid "Fallback font path"
-msgstr "Chemin de police alternative"
+msgstr "Chemin de la police alternative"
 
 #: src/settings_translation_file.cpp
 msgid "Fast key"
-msgstr "Mode rapide"
+msgstr "Touche mode rapide"
 
 #: src/settings_translation_file.cpp
 msgid "Fast mode acceleration"
@@ -3360,12 +3456,11 @@ msgid "Fast movement"
 msgstr "Mouvement rapide"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Mouvement rapide (via la touche « spécial »).\n"
+"Mouvement rapide (via la touche « Aux1 »).\n"
 "Nécessite le privilège « fast » sur le serveur."
 
 #: src/settings_translation_file.cpp
@@ -3382,9 +3477,8 @@ msgid ""
 "the\n"
 "Multiplayer Tab."
 msgstr ""
-"Fichier localisé dans client/serverlist/ contenant vos serveurs favoris "
-"affichés dans\n"
-"l'onglet multijoueur."
+"Fichier dans « client/serverlist/ » contenant vos serveurs favoris affichés "
+"dans l'onglet « Rejoindre une partie »."
 
 #: src/settings_translation_file.cpp
 msgid "Filler depth"
@@ -3399,7 +3493,6 @@ msgid "Filmic tone mapping"
 msgstr "Mappage de tons filmique"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3408,9 +3501,10 @@ msgid ""
 msgstr ""
 "Les textures filtrées peuvent mélanger des valeurs RVB avec des zones "
 "complètement transparentes, que les optimiseurs PNG ignorent généralement, "
-"aboutissant parfois à des bords foncés ou clairs sur les textures "
+"aboutissant souvent à des bords foncés ou clairs sur les textures "
 "transparentes.\n"
-"Appliquer ce filtre pour nettoyer cela au chargement de la texture."
+"Appliquer ce filtre pour nettoyer cela au chargement de la texture. Ceci est "
+"automatiquement activé si le mip-mapping est activé."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3419,8 +3513,8 @@ msgstr "Filtrage"
 #: src/settings_translation_file.cpp
 msgid "First of 4 2D noises that together define hill/mountain range height."
 msgstr ""
-"Le premier des 4 bruits 2D qui définissent la hauteur des collines et "
-"montagnes."
+"Le premier des 4 bruits 2D qui définissent ensemble la hauteur des collines "
+"et des montagnes."
 
 #: src/settings_translation_file.cpp
 msgid "First of two 3D noises that together define tunnels."
@@ -3436,35 +3530,35 @@ msgstr "Fixer la manette virtuelle"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland density"
-msgstr "Densité des massifs volants"
+msgstr "Densité des terrains flottants"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland maximum Y"
-msgstr "Maximum Y de massifs volants"
+msgstr "Maximum Y des terrains flottants"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland minimum Y"
-msgstr "Minimum Y des massifs volants"
+msgstr "Minimum Y des terrains flottants"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland noise"
-msgstr "Bruit des massifs volants"
+msgstr "Bruit des terrains flottants"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland taper exponent"
-msgstr "Paramètre de forme des massifs volants"
+msgstr "Exposant de l'effilement des terrains flottants"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland tapering distance"
-msgstr "Hauteur des bases des massifs volants"
+msgstr "Hauteur de la base des terrains flottants"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland water level"
-msgstr "Niveau d'eau des massifs volants"
+msgstr "Niveau d'eau des terrains flottants"
 
 #: src/settings_translation_file.cpp
 msgid "Fly key"
-msgstr "Voler"
+msgstr "Touche voler"
 
 #: src/settings_translation_file.cpp
 msgid "Flying"
@@ -3480,15 +3574,15 @@ msgstr "Début du brouillard"
 
 #: src/settings_translation_file.cpp
 msgid "Fog toggle key"
-msgstr "Brouillard"
+msgstr "Touche brouillard"
 
 #: src/settings_translation_file.cpp
 msgid "Font bold by default"
-msgstr "La police est en gras par défaut"
+msgstr "Police en gras par défaut"
 
 #: src/settings_translation_file.cpp
 msgid "Font italic by default"
-msgstr "La police est en italique par défaut"
+msgstr "Police en italique par défaut"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow"
@@ -3503,20 +3597,42 @@ msgid "Font size"
 msgstr "Taille de la police"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
-msgstr "La taille de police par défaut en point (pt)."
+msgid "Font size divisible by"
+msgstr "Taille de la police divisible par"
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Taille de la police par défaut où 1 unité = 1 pixel à 96 PPP"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr "Taille de la police monospace en point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Taille de la police monospace où 1 unité = 1 pixel à 96 PPP"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Font size of the recent chat text and chat prompt in point (pt).\n"
 "Value 0 will use the default font size."
 msgstr ""
-"Taille de police (en pt) des messages récents et du curseur.\n"
-"La valeur 0 correspond à la taille par défaut."
+"Taille de la police des messages récents de tchat et de l'invité de tchat en "
+"point (pt).\n"
+"La valeur 0 utilise la taille de police par défaut."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+"Pour les polices de style pixel qui ne s'adaptent pas bien, cela garantit "
+"que les tailles de police utilisées avec cette police seront toujours "
+"divisibles par cette valeur, en pixels. Par exemple une police de style "
+"pixel de 16 pixels de haut doit avoir cette valeur définie sur 16, alors "
+"elle ne sera jamais que de taille 16, 32, 48, etc., donc un mod demandant "
+"une taille de 25 obtiendra 32."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3524,8 +3640,8 @@ msgid ""
 "placeholders:\n"
 "@name, @message, @timestamp (optional)"
 msgstr ""
-"Format des messages de tchat des joueurs. Substituts valides : \n"
-"@name, @message, @timestamp (facultatif)"
+"Format des messages de tchat des joueurs. Substituts valides :\n"
+"@name, @message, @timestamp (optionnel)"
 
 #: src/settings_translation_file.cpp
 msgid "Format of screenshots."
@@ -3533,45 +3649,46 @@ msgstr "Format de captures d'écran."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Color"
-msgstr "Couleur d'arrière plan par défaut des formspec"
+msgstr "Couleur de l'arrière-plan par défaut des formspec"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Opacity"
-msgstr "Opacité par défaut des formspec"
+msgstr "Opacité de l'arrière-plan par défaut des formspec"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Color"
-msgstr "Couleur d'arrière plan des formspec plein écran"
+msgstr "Couleur de l'arrière-plan en plein écran des formspec"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Opacity"
-msgstr "Opacité de l'arrière plan des formspec en plein écran"
+msgstr "Opacité de l'arrière-plan en plein écran des formspec"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec default background color (R,G,B)."
-msgstr "Couleur de fond de la console du jeu (R,V,B)."
+msgstr "Couleur de l'arrière-plan par défaut des formspec (R,V,B)."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec default background opacity (between 0 and 255)."
-msgstr "Opacité de fond de la console du jeu (entre 0 et 255)."
+msgstr "Opacité de l'arrière-plan par défaut des formspec (entre 0 et 255)."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec full-screen background color (R,G,B)."
-msgstr "Couleur de fond de la console du jeu (R,V,B)."
+msgstr "Couleur de l'arrière-plan en plein écran des formspec (R,V,B)."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec full-screen background opacity (between 0 and 255)."
-msgstr "Opacité de fond de la console du jeu (entre 0 et 255)."
+msgstr ""
+"Opacité de l'arrière-plan en plein écran des formspec (entre 0 et 255)."
 
 #: src/settings_translation_file.cpp
 msgid "Forward key"
-msgstr "Avancer"
+msgstr "Touche avancer"
 
 #: src/settings_translation_file.cpp
 msgid "Fourth of 4 2D noises that together define hill/mountain range height."
 msgstr ""
-"Le quatrième des 4 bruits 2D qui définissent la hauteur des collines et "
-"montagnes."
+"Le quatrième des 4 bruits 2D qui définissent ensemble la hauteur des "
+"collines et des montagnes."
 
 #: src/settings_translation_file.cpp
 msgid "Fractal type"
@@ -3582,23 +3699,19 @@ msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 "Fraction de la distance de vue à partir de laquelle le brouillard est affiché"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Polices Freetype"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
 "nodes)."
 msgstr ""
-"Distance maximale de génération des mapblocks (16^3 blocs) depuis la "
-"position du client."
+"Distance maximale de génération des blocs depuis la position du client, "
+"établie en blocs de carte (16^3 blocs)."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are sent to clients, stated in mapblocks (16 nodes)."
 msgstr ""
-"Distance maximale d'envoi des mapblocks aux clients, établie en mapblocks "
+"Distance maximale d'envoi des blocs aux clients, établie en blocs de carte "
 "(16^3 blocs)."
 
 #: src/settings_translation_file.cpp
@@ -3610,9 +3723,9 @@ msgid ""
 "player is looking. (This can avoid mobs suddenly disappearing from view)"
 msgstr ""
 "Distance maximale à laquelle les clients ont connaissance des objets, "
-"définie en mapblocks (16 nœuds).\n"
+"établie en blocs de carte (16 nœuds).\n"
 "\n"
-"Si vous définissez une valeur supérieure à active_block_range, le serveur va "
+"Définir cela plus grand que « active_block_range », ainsi le serveur va "
 "maintenir les objets actifs jusqu’à cette distance dans la direction où un "
 "joueur regarde (cela peut éviter que des mobs disparaissent soudainement de "
 "la vue)."
@@ -3623,7 +3736,9 @@ msgstr "Plein écran"
 
 #: src/settings_translation_file.cpp
 msgid "Fullscreen mode."
-msgstr "Mode plein écran."
+msgstr ""
+"Mode plein écran.\n"
+"Un redémarrage est nécessaire après la modification de cette option."
 
 #: src/settings_translation_file.cpp
 msgid "GUI scaling"
@@ -3645,12 +3760,12 @@ msgstr "Rappels globaux"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Attributs de génération de terrain globaux.\n"
-"Dans le générateur de terrain v6, le signal « décorations » contrôle toutes "
-"les décorations sauf les arbres et l’herbe de la jungle, dans tous les "
-"autres générateurs de terrain, ce signal contrôle toutes les décorations."
+"Dans le générateur de terrain v6, le drapeau « décorations » contrôle toutes "
+"les décorations sauf les arbres et les herbes de la jungle, dans tous les "
+"autres générateurs de terrain, ce drapeau contrôle toutes les décorations."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3658,7 +3773,7 @@ msgid ""
 "Controls the contrast of the highest light levels."
 msgstr ""
 "Gradient de la courbe de lumière au niveau de lumière maximale.\n"
-"Contrôle le contraste de la lumière aux niveaux d'éclairage les plus élevés."
+"Contrôle le contraste aux niveaux d'éclairage les plus élevés."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3666,7 +3781,7 @@ msgid ""
 "Controls the contrast of the lowest light levels."
 msgstr ""
 "Gradient de la courbe de lumière au niveau de lumière minimale.\n"
-"Contrôle le contraste de la lumière aux niveaux d'éclairage les plus bas."
+"Contrôle le contraste aux niveaux d'éclairage les plus bas."
 
 #: src/settings_translation_file.cpp
 msgid "Graphics"
@@ -3682,7 +3797,7 @@ msgstr "Niveau du sol"
 
 #: src/settings_translation_file.cpp
 msgid "Ground noise"
-msgstr "Bruit pour la boue"
+msgstr "Bruit au sol"
 
 #: src/settings_translation_file.cpp
 msgid "HTTP mods"
@@ -3690,11 +3805,11 @@ msgstr "Mods HTTP"
 
 #: src/settings_translation_file.cpp
 msgid "HUD scale factor"
-msgstr "Facteur mise à l'échelle du HUD"
+msgstr "Facteur de mise à l'échelle de l'interface"
 
 #: src/settings_translation_file.cpp
 msgid "HUD toggle key"
-msgstr "HUD"
+msgstr "Touche HUD"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3703,11 +3818,11 @@ msgid ""
 "-    log: mimic and log backtrace of deprecated call (default).\n"
 "-    error: abort on usage of deprecated call (suggested for mod developers)."
 msgstr ""
-"Traitement des appels d'API Lua obsolètes : \n"
-"– aucun : N'enregistre pas les appels obsolètes\n"
-"– journal : imite et enregistre la trace des appels obsolètes (par défaut en "
+"Traitement des appels d'API Lua obsolètes :\n"
+"– aucun : n'enregistre pas les appels obsolètes\n"
+"– journal : imite et enregistre la trace des appels obsolètes (par défaut en "
 "mode debug).\n"
-"– erreur : s'interrompt lors d'un appel obsolète (recommandé pour les "
+"– erreur : s'interrompt lors d'un appel obsolète (recommandé pour les "
 "développeurs de mods)."
 
 #: src/settings_translation_file.cpp
@@ -3718,11 +3833,11 @@ msgid ""
 "call).\n"
 "* Instrument the sampler being used to update the statistics."
 msgstr ""
-"Auto-instrumentaliser le profileur : \n"
-"* Instrumentalise une fonction vide.\n"
-"La surcharge sera évaluée. (l'auto-instrumentalisation ajoute 1 appel de "
+"Auto-instrumentaliser le profileur :\n"
+"* Instrumentalise une fonction vide.\n"
+"La surcharge est évaluée (l'auto-instrumentalisation ajoute 1 appel de "
 "fonction à chaque fois).\n"
-"* Instrumentalise l’échantillonneur utilisé pour mettre à jour les "
+"* Instrumentalise l’échantillonneur utilisé pour mettre à jour les "
 "statistiques."
 
 #: src/settings_translation_file.cpp
@@ -3734,10 +3849,11 @@ msgid "Heat noise"
 msgstr "Bruit de chaleur"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Composant de hauteur de la taille initiale de la fenêtre."
+msgstr ""
+"Composant de hauteur de la taille initiale de la fenêtre. Ignoré en mode "
+"plein écran."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3757,19 +3873,19 @@ msgstr "Seuil des collines"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness1 noise"
-msgstr "Bruit de collines1"
+msgstr "Bruit de collines nº 1"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness2 noise"
-msgstr "Bruit de collines2"
+msgstr "Bruit de collines nº 2"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness3 noise"
-msgstr "Bruit de collines3"
+msgstr "Bruit de collines nº 3"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness4 noise"
-msgstr "Bruit de collines4"
+msgstr "Bruit de collines nº 4"
 
 #: src/settings_translation_file.cpp
 msgid "Homepage of server, to be displayed in the serverlist."
@@ -3780,24 +3896,24 @@ msgid ""
 "Horizontal acceleration in air when jumping or falling,\n"
 "in nodes per second per second."
 msgstr ""
-"Accélération horizontale dans l'air en sautant ou en tombant,\n"
-"en nœuds par seconde par seconde."
+"Accélération horizontale dans l'air en sautant ou en tombant, en nœuds par "
+"seconde par seconde."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Horizontal and vertical acceleration in fast mode,\n"
 "in nodes per second per second."
 msgstr ""
-"Accélération horizontale et verticale en mode rapide,\n"
-"en nœuds par seconde par seconde."
+"Accélération horizontale et verticale en mode rapide, en nœuds par seconde "
+"par seconde."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Horizontal and vertical acceleration on ground or when climbing,\n"
 "in nodes per second per second."
 msgstr ""
-"Accélération horizontale et verticale au sol ou en montée,\n"
-"en blocs par seconde."
+"Accélération horizontale et verticale au sol ou en montée, en nœuds par "
+"seconde."
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar next key"
@@ -3809,131 +3925,131 @@ msgstr "Touche précédent sur la barre d'actions"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 1 key"
-msgstr "Touche de l'emplacement 1 de la barre d'action"
+msgstr "Touche emplacement 1 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 10 key"
-msgstr "Touche de l'emplacement 10 de la barre d'action"
+msgstr "Touche emplacement 10 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 11 key"
-msgstr "Touche de l'emplacement 11 de la barre d'action"
+msgstr "Touche emplacement 11 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 12 key"
-msgstr "Touche de l'emplacement 12 de la barre d'action"
+msgstr "Touche emplacement 12 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 13 key"
-msgstr "Touche de l'emplacement 13 de la barre d'action"
+msgstr "Touche emplacement 13 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 14 key"
-msgstr "Touche de l'emplacement 14 de la barre d'action"
+msgstr "Touche emplacement 14 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 15 key"
-msgstr "Touche de l'emplacement 15 de la barre d'action"
+msgstr "Touche emplacement 15 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 16 key"
-msgstr "Touche de l'emplacement 16 de la barre d'action"
+msgstr "Touche emplacement 16 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 17 key"
-msgstr "Touche de l'emplacement 17 de la barre d'action"
+msgstr "Touche emplacement 17 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 18 key"
-msgstr "Touche de l'emplacement 18 de la barre d'action"
+msgstr "Touche emplacement 18 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 19 key"
-msgstr "Touche de l'emplacement 19 de la barre d'action"
+msgstr "Touche emplacement 19 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 2 key"
-msgstr "Touche de l'emplacement 2 de la barre d'action"
+msgstr "Touche emplacement 2 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 20 key"
-msgstr "Touche de l'emplacement 20 de la barre d'action"
+msgstr "Touche emplacement 20 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 21 key"
-msgstr "Touche de l'emplacement 21 de la barre d'action"
+msgstr "Touche emplacement 21 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 22 key"
-msgstr "Touche de l'emplacement 22 de la barre d'action"
+msgstr "Touche emplacement 22 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 23 key"
-msgstr "Touche de l'emplacement 23 de la barre d'action"
+msgstr "Touche emplacement 23 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 24 key"
-msgstr "Touche de l'emplacement 24 de la barre d'action"
+msgstr "Touche emplacement 24 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 25 key"
-msgstr "Touche de l'emplacement 25 de la barre d'action"
+msgstr "Touche emplacement 25 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 26 key"
-msgstr "Touche de l'emplacement 26 de la barre d'action"
+msgstr "Touche emplacement 26 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 27 key"
-msgstr "Touche de l'emplacement 27 de la barre d'action"
+msgstr "Touche emplacement 27 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 28 key"
-msgstr "Touche de l'emplacement 28 de la barre d'action"
+msgstr "Touche emplacement 28 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 29 key"
-msgstr "Touche de l'emplacement 29 de la barre d'action"
+msgstr "Touche emplacement 29 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 3 key"
-msgstr "Touche de l'emplacement 3 de la barre d'action"
+msgstr "Touche emplacement 3 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 30 key"
-msgstr "Touche de l'emplacement 30 de la barre d'action"
+msgstr "Touche emplacement 30 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 31 key"
-msgstr "Touche de l'emplacement 31 de la barre d'action"
+msgstr "Touche emplacement 31 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 32 key"
-msgstr "Touche de l'emplacement 32 de la barre d'action"
+msgstr "Touche emplacement 32 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 4 key"
-msgstr "Touche de l'emplacement 4 de la barre d'action"
+msgstr "Touche emplacement 4 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 5 key"
-msgstr "Touche de l'emplacement 5 de la barre d'action"
+msgstr "Touche emplacement 5 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 6 key"
-msgstr "Touche de l'emplacement 6 de la barre d'action"
+msgstr "Touche emplacement 6 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 7 key"
-msgstr "Touche de l'emplacement 7 de la barre d'action"
+msgstr "Touche emplacement 7 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 8 key"
-msgstr "Touche de l'emplacement 8 de la barre d'action"
+msgstr "Touche emplacement 8 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 9 key"
-msgstr "Touche de l'emplacement 9 de la barre d'action"
+msgstr "Touche emplacement 9 de la barre d'action"
 
 #: src/settings_translation_file.cpp
 msgid "How deep to make rivers."
@@ -3955,10 +4071,9 @@ msgid ""
 "How much the server will wait before unloading unused mapblocks.\n"
 "Higher value is smoother, but will use more RAM."
 msgstr ""
-"Délai maximal jusqu'où le serveur va attendre avant de purger les mapblocks "
-"inactifs.\n"
-"Une valeur plus grande est plus confortable, mais utilise davantage de "
-"mémoire."
+"Combien de temps le serveur attendra avant de décharger les blocs de carte "
+"inutilisés.\n"
+"Une valeur plus élevée est plus fluide, mais utilise plus de RAM."
 
 #: src/settings_translation_file.cpp
 msgid "How wide to make rivers."
@@ -3966,15 +4081,15 @@ msgstr "Quelle largeur doivent avoir les rivières."
 
 #: src/settings_translation_file.cpp
 msgid "Humidity blend noise"
-msgstr "Bruit de fusion d'humidité"
+msgstr "Bruit de mélange de l'humidité"
 
 #: src/settings_translation_file.cpp
 msgid "Humidity noise"
-msgstr "Bruit d'humidité"
+msgstr "Bruit de l'humidité"
 
 #: src/settings_translation_file.cpp
 msgid "Humidity variation for biomes."
-msgstr "Variation d'humidité pour les biomes."
+msgstr "Variation de l'humidité pour les biomes."
 
 #: src/settings_translation_file.cpp
 msgid "IPv6"
@@ -3989,18 +4104,17 @@ msgid ""
 "If FPS would go higher than this, limit it by sleeping\n"
 "to not waste CPU power for no benefit."
 msgstr ""
-"Si le nombre d'images par seconde (FPS) veut aller au-delà de cette valeur, "
-"il est limité\n"
-"pour ne pas gaspiller inutilement les ressources du processeur."
+"Si les FPS (nombre d'images par seconde) sont supérieurs à cette valeur, "
+"limitez-les en les mettant en sommeil pour ne pas gaspiller la puissance du "
+"CPU sans aucun bénéfice."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Si désactivé, la touche « spécial » est utilisée pour voler vite si les "
-"modes vol et rapide sont activés."
+"Si désactivé, la touche « Aux1 » est utilisée pour voler vite si les modes "
+"vol et rapide sont activés."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4010,11 +4124,11 @@ msgid ""
 "invisible\n"
 "so that the utility of noclip mode is reduced."
 msgstr ""
-"Si activé, le serveur n'enverra pas les blocs qui ne sont pas visibles par\n"
-"le client en fonction de sa position. Cela peut réduire de 50 % à 80 %\n"
-"le nombre de blocs envoyés. Le client ne pourra plus voir ces blocs à moins\n"
-"de se déplacer, ce qui réduit l'efficacité des tricheries du style « noclip "
-"»."
+"Si activé, le serveur effectuera la détermination des blocs de la carte "
+"invisibles selon la position des yeux du joueur.\n"
+"Cela peut réduire le nombre de blocs envoyés au client de 50 à 80 %.\n"
+"Le client ne recevra plus la plupart de blocs invisibles, de sorte que "
+"l'utilité du mode « noclip » est réduite."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4027,14 +4141,13 @@ msgstr ""
 "Nécessite le privilège « noclip » sur le serveur."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Si activé, la touche « spécial » est utilisée à la place de la touche "
-"« s’accroupir » pour monter ou descendre."
+"Si activé, la touche « Aux1 » est utilisée à la place de la touche « Marcher "
+"lentement » pour monter ou descendre."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4078,7 +4191,7 @@ msgid ""
 "This is helpful when working with nodeboxes in small areas."
 msgstr ""
 "Si activé, vous pourrez placer des blocs à la position où vous êtes.\n"
-"C'est utile quand vous travaillez avec des modèles nodebox dans des zones "
+"C'est utile pour travailler avec des modèles « nodebox » dans des zones "
 "exiguës."
 
 #: src/settings_translation_file.cpp
@@ -4087,14 +4200,17 @@ msgid ""
 "limited\n"
 "to this distance from the player to the node."
 msgstr ""
-"Si la restriction CSM pour la distance des blocs est activé, les appels "
-"get_node sont limités à la distance entre le joueur et le bloc."
+"Si la restriction « CSM » pour la distance des blocs est activée, les appels "
+"« get_node » sont limités à la distance entre le joueur et le bloc."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Si l'exécution d'une commande de tchat prend plus de temps que cette durée "
+"spécifiée en secondes, ajoute les informations de temps au message de la "
+"commande de tchat."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4103,11 +4219,10 @@ msgid ""
 "deleting an older debug.txt.1 if it exists.\n"
 "debug.txt is only moved if this setting is positive."
 msgstr ""
-"Si la taille du fichier debug.txt dépasse le nombre de mégaoctets spécifié "
-"dans\n"
-"ce paramètre une fois ouvert, le fisher est déplacé vers debug.txt.1 et\n"
-"supprimera un ancien debug.txt.1 s'il existe.\n"
-"debug.txt n'est déplacé que si ce paramètre est positif."
+"Si la taille du fichier « debug.txt » dépasse le nombre de mégaoctets "
+"spécifié par ce paramètre ; une fois ouvert, le fichier est déplacé vers "
+"« debug.txt.1 » et supprime l'ancien « debug.txt.1 » s'il existe.\n"
+"« debug.tx t» est déplacé seulement si ce paramètre est activé."
 
 #: src/settings_translation_file.cpp
 msgid "If this is set, players will always (re)spawn at the given position."
@@ -4123,24 +4238,26 @@ msgstr "Dans le jeu"
 
 #: src/settings_translation_file.cpp
 msgid "In-game chat console background alpha (opaqueness, between 0 and 255)."
-msgstr "Opacité de fond de la console du jeu (entre 0 et 255)."
+msgstr ""
+"Opacité de l'arrière-plan de la console de tchat dans le jeu (entre 0 et "
+"255)."
 
 #: src/settings_translation_file.cpp
 msgid "In-game chat console background color (R,G,B)."
-msgstr "Couleur de fond de la console du jeu (R,V,B)."
+msgstr "Couleur de l'arrière-plan de la console de tchat dans le jeu (R,V,B)."
 
 #: src/settings_translation_file.cpp
 msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)."
 msgstr ""
-"Hauteur de la console de tchat du jeu, entre 0,1 (10 %) et 1,0 (100 %)."
+"Hauteur de la console de tchat dans le jeu, entre 0,1 (10 %) et 1,0 (100 %)."
 
 #: src/settings_translation_file.cpp
 msgid "Inc. volume key"
-msgstr "Touche d'augmentation de volume"
+msgstr "Touche augmenter le volume"
 
 #: src/settings_translation_file.cpp
 msgid "Initial vertical speed when jumping, in nodes per second."
-msgstr "Vitesse verticale initiale lors du saut, en blocs par seconde."
+msgstr "Vitesse verticale initiale lors du saut, en nœuds par seconde."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4152,7 +4269,7 @@ msgstr ""
 "noyau"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr "Instrument d'enregistrement des commandes de tchat."
 
 #: src/settings_translation_file.cpp
@@ -4188,8 +4305,8 @@ msgstr "Instrumentalisation"
 #: src/settings_translation_file.cpp
 msgid "Interval of saving important changes in the world, stated in seconds."
 msgstr ""
-"Intervalle de sauvegarde des changements importants dans le monde, établie "
-"en secondes."
+"Intervalle de sauvegarde des changements importants dans le monde, établi en "
+"secondes."
 
 #: src/settings_translation_file.cpp
 msgid "Interval of sending time of day to clients."
@@ -4201,7 +4318,7 @@ msgstr "Animation des items d'inventaire"
 
 #: src/settings_translation_file.cpp
 msgid "Inventory key"
-msgstr "Touche d'inventaire"
+msgstr "Touche inventaire"
 
 #: src/settings_translation_file.cpp
 msgid "Invert mouse"
@@ -4213,15 +4330,15 @@ msgstr "Inverser les mouvements verticaux de la souris."
 
 #: src/settings_translation_file.cpp
 msgid "Italic font path"
-msgstr "Chemin de la police Italique"
+msgstr "Chemin de la police italique"
 
 #: src/settings_translation_file.cpp
 msgid "Italic monospace font path"
-msgstr "Chemin de la police Italique Monospace"
+msgstr "Chemin de la police monospace en italique"
 
 #: src/settings_translation_file.cpp
 msgid "Item entity TTL"
-msgstr "Durée de vie des items abandonnés"
+msgstr "Temps de vie des entités objets"
 
 #: src/settings_translation_file.cpp
 msgid "Iterations"
@@ -4235,7 +4352,7 @@ msgid ""
 "At iterations = 20 this mapgen has a similar load to mapgen V7."
 msgstr ""
 "Itérations de la fonction récursive.\n"
-"L'augmenter augmente la quantité de détails, mais également la charge du "
+"L'augmenter, augmente la quantité de détails, mais également la charge du "
 "processeur.\n"
 "Quand itérations = 20 cette méthode de génération est aussi gourmande en "
 "ressources que la méthode v7."
@@ -4249,7 +4366,7 @@ msgid "Joystick button repetition interval"
 msgstr "Intervalle de répétition des boutons de la manette"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Zone morte de la manette"
 
 #: src/settings_translation_file.cpp
@@ -4328,7 +4445,7 @@ msgstr "Julia z"
 
 #: src/settings_translation_file.cpp
 msgid "Jump key"
-msgstr "Sauter"
+msgstr "Touche sauter"
 
 #: src/settings_translation_file.cpp
 msgid "Jumping speed"
@@ -4340,7 +4457,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour diminuer le champ de vision.\n"
+"Touche pour réduire la distance d'affichage.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4350,7 +4467,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour diminuer le volume.\n"
+"Touche pour réduire le volume.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4370,7 +4487,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour jeter l'objet sélectionné.\n"
+"Touche pour lâcher l'objet sélectionné.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4380,7 +4497,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour accroitre le champ de vision.\n"
+"Touche pour augmenter la distance d'affichage.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4421,8 +4538,8 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour faire reculer le joueur.\n"
-"Désactive également l’avance auto., lorsqu’elle est active.\n"
+"Touche pour déplacer le joueurs en arrière.\n"
+"Désactive également l’avance automatique, lorsqu’elle est active.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4472,7 +4589,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour ouvrir la fenêtre du tchat pour entrer des commandes.\n"
+"Touche pour ouvrir la fenêtre de tchat pour entrer des commandes.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4482,7 +4599,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour ouvrir la fenêtre du tchat pour entrer des commandes locales.\n"
+"Touche pour ouvrir la fenêtre de tchat pour entrer des commandes locales.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4522,7 +4639,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour sélectionner le prochain item dans la barre d'action.\n"
+"Touche pour sélectionner la 11ᵉ case de la barre d'action.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4662,7 +4779,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour sélectionner la 30ᵉ case de la barre d'action.\n"
+"Touche pour sélectionner la 25ᵉ case de la barre d'action.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4782,7 +4899,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour sélectionner le prochain item dans la barre d'action.\n"
+"Touche pour sélectionner l'objet suivant dans la barre d'action.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4802,7 +4919,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour sélectionner l'item précédent dans la barre d'action.\n"
+"Touche pour sélectionner l'objet précédent dans la barre d'action.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4852,7 +4969,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour sélectionner le prochain item dans la barre d'action.\n"
+"Touche pour sélectionner la troisième case de la barre d'action.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4864,9 +4981,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour se faufiler.\n"
-"Egalement utilisée pour descendre et plonger dans l'eau si aux1_descends est "
-"désactivé.\n"
+"Touche pour se déplacer lentement.\n"
+"Également utilisée pour descendre et plonger dans l'eau si « aux1_descends » "
+"est désactivé.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4876,7 +4993,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour changer de vue entre la 1ère et 3ème personne.\n"
+"Touche pour changer de vue entre la première et troisième personne.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4896,7 +5013,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche d’exécution automatique.\n"
+"Touche d'avance automatique.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4956,7 +5073,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Toucher pour passer en mode de direction libre.\n"
+"Touche pour passer en mode de direction libre.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -5007,7 +5124,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour afficher/masquer le HUD ( Affichage tête haute).\n"
+"Touche pour afficher/masquer le HUD (affichage tête haute).\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -5027,8 +5144,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour afficher/cacher la zone de profilage. Utilisé pour le "
-"développement.\n"
+"Touche pour afficher/cacher le profileur. Utilisé pour le développement.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -5048,7 +5164,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Touche pour zoomer (lorsque c'est possible).\n"
+"Touche pour zoomer si possible.\n"
 "Voir http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -5071,7 +5187,7 @@ msgstr "Langue"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave depth"
-msgstr "Profondeur des grandes caves"
+msgstr "Profondeur de grandes grottes"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave maximum number"
@@ -5087,11 +5203,11 @@ msgstr "Proportion de grandes grottes inondées"
 
 #: src/settings_translation_file.cpp
 msgid "Large chat console key"
-msgstr "Touche de grande console de tchat"
+msgstr "Touche grande console de tchat"
 
 #: src/settings_translation_file.cpp
 msgid "Leaves style"
-msgstr "Apparence des feuilles d'arbres"
+msgstr "Apparence des feuilles"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5100,11 +5216,11 @@ msgid ""
 "-   Simple: only outer faces, if defined special_tiles are used\n"
 "-   Opaque: disable transparency"
 msgstr ""
-"Apparence des feuilles d’arbres : \n"
-"– Détaillée : toutes les faces sont visibles\n"
-"– Simple : seulement les faces externes, si des « special_tiles » sont "
+"Apparence des feuilles d’arbres :\n"
+"– Détaillée : toutes les faces sont visibles\n"
+"– Simple : seulement les faces externes, si des « special_tiles » sont "
 "définies\n"
-"– Opaque : désactive la transparence"
+"– Opaque : désactive la transparence"
 
 #: src/settings_translation_file.cpp
 msgid "Left key"
@@ -5149,8 +5265,8 @@ msgid ""
 "-    info\n"
 "-    verbose"
 msgstr ""
-"Niveau de journalisation à écrire dans debug.txt : \n"
-"– <rien> (pas de journalisation)\n"
+"Niveau de journalisation à écrire dans « debug.txt » :\n"
+"– < rien > (pas de journalisation)\n"
 "– aucun (messages sans niveau)\n"
 "– erreur\n"
 "– avertissement\n"
@@ -5168,11 +5284,11 @@ msgstr "Centre d'amplification de la courbe de lumière"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve boost spread"
-msgstr "Étalement du boost de la courbe de lumière"
+msgstr "Étalement de l'amplification de la courbe de lumière"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve gamma"
-msgstr "Courbe de lumière gamma"
+msgstr "Gamma de la courbe de lumière"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve high gradient"
@@ -5190,7 +5306,8 @@ msgid ""
 msgstr ""
 "Limite du générateur de terrain, en nœuds, dans les 6 directions à partir de "
 "(0,0,0).\n"
-"Seules les tranches totalement comprises dans cette limite sont générées.\n"
+"Seules les tranches de la carte totalement comprises dans cette limite sont "
+"générées.\n"
 "Valeur différente pour chaque monde."
 
 #: src/settings_translation_file.cpp
@@ -5201,10 +5318,10 @@ msgid ""
 "-    Downloads performed by main menu (e.g. mod manager).\n"
 "Only has an effect if compiled with cURL."
 msgstr ""
-"Nombre limite de requête HTTP en parallèle. Affecte : \n"
-"– L'obtention de média si le serveur utilise l'option remote_media.\n"
+"Nombre limite de requête HTTP en parallèle. Affecte :\n"
+"– L'obtention de média si le serveur utilise le paramètre « remote_media ».\n"
 "– Le téléchargement de la liste des serveurs et l'annonce du serveur.\n"
-"– Les téléchargements effectués par le menu (ex. : gestionnaire de mods).\n"
+"– Les téléchargements effectués par le menu (ex. : gestionnaire de mods).\n"
 "Prend seulement effet si Minetest est compilé avec cURL."
 
 #: src/settings_translation_file.cpp
@@ -5237,7 +5354,7 @@ msgstr "Intervalle de mise à jour des liquides"
 
 #: src/settings_translation_file.cpp
 msgid "Load the game profiler"
-msgstr "Charger le profil de jeu"
+msgstr "Charger le profileur du jeu"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5245,8 +5362,8 @@ msgid ""
 "Provides a /profiler command to access the compiled profile.\n"
 "Useful for mod developers and server operators."
 msgstr ""
-"Charge le profil du jeu pour collecter des données de profil du jeu.\n"
-"Fournit une commande /profiler pour accéder au profil compilé.\n"
+"Charge le profileur du jeu pour collecter des données de profilage du jeu.\n"
+"Fournit une commande « /profiler » pour accéder au profil compilé.\n"
 "Utile pour les développeurs de mod et les opérateurs de serveurs."
 
 #: src/settings_translation_file.cpp
@@ -5259,7 +5376,7 @@ msgstr "Limite basse Y des donjons."
 
 #: src/settings_translation_file.cpp
 msgid "Lower Y limit of floatlands."
-msgstr "Borne inférieure Y des massifs volants."
+msgstr "Limite basse Y des terrains flottants."
 
 #: src/settings_translation_file.cpp
 msgid "Main menu script"
@@ -5308,8 +5425,8 @@ msgid ""
 "ocean, islands and underground."
 msgstr ""
 "Attributs spécifiques au générateur de terrain fractal.\n"
-"« terrain » active la création de terrain non fractal : océan, îles et "
-"souterrain."
+"« terrain » active la création de terrains non fractals : océans, îles et "
+"souterrains."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5321,11 +5438,11 @@ msgid ""
 "'altitude_dry': Reduces humidity with altitude."
 msgstr ""
 "Attributs spécifiques au générateur de terrain vallées.\n"
-"« altitude_chill » : Réduit la chaleur avec l’altitude.\n"
-"« humid_rivers » : Augmente l’humidité autour des rivières.\n"
-"« vary_river_dept » : Si activé, une humidité basse et une forte chaleur "
-"rendent les rivières moins profondes et parfois asséchées.\n"
-"« altitude_dry » : Réduit l’humidité avec l’altitude."
+"« altitude_chill » : réduit la chaleur avec l’altitude.\n"
+"« humid_rivers » : augmente l’humidité autour des rivières.\n"
+"« vary_river_dept » : si activé, une humidité basse et une chaleur élevée "
+"rendent les rivières moins profondes et parfois sèches.\n"
+"« altitude_dry » : réduit l’humidité avec l’altitude."
 
 #: src/settings_translation_file.cpp
 msgid "Map generation attributes specific to Mapgen v5."
@@ -5340,8 +5457,8 @@ msgid ""
 msgstr ""
 "Attributs spécifiques au générateur de terrain v6.\n"
 "Le drapeau « snowbiomes » active le nouveau système à 5 biomes.\n"
-"Sous ce nouveau système, la création de jungles est automatique et le "
-"drapeau « jungles » est ignoré."
+"Lorsque le drapeau « snowbiomes » est activé, les jungles sont "
+"automatiquement activées et le drapeau « jungles » est ignoré."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5351,38 +5468,38 @@ msgid ""
 "'caverns': Giant caves deep underground."
 msgstr ""
 "Attributs spécifiques au générateur de terrain v7.\n"
-"« crêtes » : pour des rivières.\n"
-"« massifs volant » : massifs de terres atmosphérique.\n"
-"« cavernes » : pour des grottes immenses et profondes."
+"« montagnes » : montagnes.\n"
+"« crêtes » : rivières.\n"
+"« terrains flottants » : vaste terrain flottant dans l'atmosphère.\n"
+"« cavernes » : cavernes immenses souterraines profondes."
 
 #: src/settings_translation_file.cpp
 msgid "Map generation limit"
-msgstr "Limites de génération du terrain"
+msgstr "Limite de génération du terrain"
 
 #: src/settings_translation_file.cpp
 msgid "Map save interval"
 msgstr "Intervalle de sauvegarde de la carte"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Intervalle de mise à jour des liquides"
+msgid "Map shadows update frames"
+msgstr "Images de mise à jour des ombres de la carte"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
-msgstr "Limite des mapblocks"
+msgstr "Limite des blocs de carte"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock mesh generation delay"
-msgstr "Délai de génération des maillages de MapBlocks"
+msgstr "Délai de génération des maillages de blocs de carte"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock mesh generator's MapBlock cache size in MB"
-msgstr "Taille du cache de MapBlocks en Mo du générateur de maillage"
+msgstr "Taille du cache de blocs de carte en Mo du générateur de maillage"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock unload timeout"
-msgstr "Délais d'interruption du déchargement des mapblocks"
+msgstr "Délai d'interruption du déchargement de blocs de carte"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen Carpathian"
@@ -5442,7 +5559,7 @@ msgstr "Drapeaux spécifiques au générateur de terrain vallées"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen debug"
-msgstr "Débogage de la génération du terrain"
+msgstr "Débogage de la génération de terrain"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen name"
@@ -5450,11 +5567,11 @@ msgstr "Nom du générateur de terrain"
 
 #: src/settings_translation_file.cpp
 msgid "Max block generate distance"
-msgstr "Distance maximale de génération des mapblocks"
+msgstr "Distance maximale de génération de blocs"
 
 #: src/settings_translation_file.cpp
 msgid "Max block send distance"
-msgstr "Distance maximale d'envoi des mapblocks"
+msgstr "Distance maximale d'envoi de blocs"
 
 #: src/settings_translation_file.cpp
 msgid "Max liquids processed per step."
@@ -5462,7 +5579,7 @@ msgstr "Maximum de liquides traités par étape de serveur."
 
 #: src/settings_translation_file.cpp
 msgid "Max. clearobjects extra blocks"
-msgstr "Maximum d'extra-mapblocks par clearobjects"
+msgstr "Blocs supplémentaires maximum de « clearobjects »"
 
 #: src/settings_translation_file.cpp
 msgid "Max. packets per iteration"
@@ -5480,11 +5597,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Distance maximale pour le rendu des ombres."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
-msgstr "Mapblocks maximum chargés de force"
+msgstr "Blocs maximum chargés de force"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum hotbar width"
@@ -5493,11 +5610,12 @@ msgstr "Largeur maximale de la barre d'inventaire"
 #: src/settings_translation_file.cpp
 msgid "Maximum limit of random number of large caves per mapchunk."
 msgstr ""
-"Limite maximale pour le nombre aléatoire de grandes grottes par mapchunk."
+"Limite maximale du nombre aléatoire de grandes grottes par tranche de carte."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum limit of random number of small caves per mapchunk."
-msgstr "Limite maximale du nombre aléatoire de petites grottes par mapchunk."
+msgstr ""
+"Limite maximale du nombre aléatoire de petites grottes par tranche de carte."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5514,29 +5632,32 @@ msgid ""
 "max_total = ceil((#clients + max_users) * per_client / 4)"
 msgstr ""
 "Le nombre maximal de blocs qui sont envoyés simultanément par client.\n"
-"Le compte total maximal est calculé dynamiquement : \n"
+"Le compte total maximal est calculé dynamiquement :\n"
 "max_total = ceil((nbre clients + max_users) × per_client ÷ 4)"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of blocks that can be queued for loading."
-msgstr "Nombre maximal de mapblocks qui peuvent être listés pour chargement."
+msgstr ""
+"Nombre maximal de blocs qui peuvent être mis en file d'attente pour "
+"chargement."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum number of blocks to be queued that are to be generated.\n"
 "This limit is enforced per player."
 msgstr ""
-"Nombre maximal de mapblocks à lister qui doivent être générés.\n"
-"Laisser ce champ vide pour un montant approprié défini automatiquement."
+"Nombre maximal de blocs à mettre en file d'attente qui doivent être "
+"générés.\n"
+"Cette limite est appliquée par joueur."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum number of blocks to be queued that are to be loaded from file.\n"
 "This limit is enforced per player."
 msgstr ""
-"Nombre maximal de mapblocks à lister qui doivent être générés depuis un "
-"fichier.\n"
-"Laisser ce champ vide pour un montant approprié défini automatiquement."
+"Nombre maximal de blocs à mettre en file d'attente qui doivent être chargés "
+"depuis un fichier.\n"
+"Cette limite est appliquée par joueur."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5546,18 +5667,18 @@ msgid ""
 msgstr ""
 "Nombre maximal de téléchargements simultanés. Les téléchargements dépassant "
 "cette limite seront mis en file d'attente.\n"
-"Ce nombre doit être inférieur à la limite de curl_parallel_limit."
+"Ce nombre doit être inférieur à la limite de « curl_parallel_limit »."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of forceloaded mapblocks."
-msgstr "Nombre maximal de mapblocks chargés de force."
+msgstr "Nombre maximal de blocs de carte chargés de force."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum number of mapblocks for client to be kept in memory.\n"
 "Set to -1 for unlimited amount."
 msgstr ""
-"Nombre maximal de mapblocks gardés dans la mémoire du client.\n"
+"Nombre maximal de blocs de carte pour le client à garder en mémoire.\n"
 "Définir à -1 pour un montant illimité."
 
 #: src/settings_translation_file.cpp
@@ -5567,7 +5688,7 @@ msgid ""
 "client number."
 msgstr ""
 "Nombre maximal de paquets envoyés par étape d'envoi. Si vous avez une "
-"connexion lente, essayez de réduire cette valeur, mais réduisez pas cette "
+"connexion lente, essayer de réduire cette valeur, mais ne pas réduire cette "
 "valeur en-dessous du double du nombre de clients maximum sur le serveur."
 
 #: src/settings_translation_file.cpp
@@ -5580,7 +5701,8 @@ msgstr "Nombre maximal de message récent à afficher"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of statically stored objects in a block."
-msgstr "Nombre maximal d'objets sauvegardés dans un mapblock (16^3 blocs)."
+msgstr ""
+"Nombre maximal d'objets sauvegardés dans un bloc de carte (16^3 blocs)."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum objects per block"
@@ -5607,23 +5729,25 @@ msgid ""
 "Maximum size of the out chat queue.\n"
 "0 to disable queueing and -1 to make the queue size unlimited."
 msgstr ""
-"Taille maximale de la file d’attente sortante de la discussion.\n"
-"0 pour désactiver la file d’attente et -1 pour rendre la taille infinie."
+"Taille maximale de la file de sortie de message du tchat.\n"
+"0 pour désactiver la file de sortie et -1 pour rendre la taille de la file "
+"de sortie illimitée."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Délais maximaux de téléchargement d'un fichier (ex. : un mod), établi en "
-"millisecondes."
+"Durée maximale qu'un téléchargement de fichier (ex. : un téléchargement de "
+"mod) peut prendre, établie en millisecondes."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Durée maximale qu'une requête interactive (ex. : récupération de la liste de "
+"serveurs) peut prendre, établie en millisecondes."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5659,7 +5783,7 @@ msgstr "Mini-carte"
 
 #: src/settings_translation_file.cpp
 msgid "Minimap key"
-msgstr "Mini-carte"
+msgstr "Touche mini-carte"
 
 #: src/settings_translation_file.cpp
 msgid "Minimap scan height"
@@ -5667,11 +5791,13 @@ msgstr "Hauteur de balayage de la mini-carte"
 
 #: src/settings_translation_file.cpp
 msgid "Minimum limit of random number of large caves per mapchunk."
-msgstr "Minimum pour le nombre de grandes grottes par mapchunk tiré au hasard."
+msgstr ""
+"Limite minimale du nombre aléatoire de grandes grottes par tranche de carte."
 
 #: src/settings_translation_file.cpp
 msgid "Minimum limit of random number of small caves per mapchunk."
-msgstr "Minimum pour le nombre de petites grottes par mapchunk tiré au hasard."
+msgstr ""
+"Limite minimale du nombre aléatoire de petites grottes par tranche de carte."
 
 #: src/settings_translation_file.cpp
 msgid "Minimum texture size"
@@ -5686,16 +5812,20 @@ msgid "Mod channels"
 msgstr "Canaux de mods"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "Modifie la taille des éléments de la barre d'action principale."
+msgid "Modifies the size of the HUD elements."
+msgstr "Modifie la taille des éléments de l'interface."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
-msgstr "Chemin de la police Monospace"
+msgstr "Chemin de la police monospace"
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font size"
-msgstr "Taille de la police Monospace"
+msgstr "Taille de la police monospace"
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr "Taille de la police monospace divisible par"
 
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
@@ -5703,7 +5833,7 @@ msgstr "Bruit de hauteur des montagnes"
 
 #: src/settings_translation_file.cpp
 msgid "Mountain noise"
-msgstr "Bruit pour les montagnes"
+msgstr "Bruit des montagnes"
 
 #: src/settings_translation_file.cpp
 msgid "Mountain variation noise"
@@ -5723,7 +5853,7 @@ msgstr "Facteur de sensibilité de la souris."
 
 #: src/settings_translation_file.cpp
 msgid "Mud noise"
-msgstr "Bruit pour la boue"
+msgstr "Bruit de boue"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5731,11 +5861,11 @@ msgid ""
 "For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
 msgstr ""
 "Facteur de mouvement de bras en tombant.\n"
-"Exemples : 0 = aucun mouvement, 1 = normal, 2 = double."
+"Exemples : 0 = aucun mouvement, 1 = normal, 2 = double."
 
 #: src/settings_translation_file.cpp
 msgid "Mute key"
-msgstr "Touche pour rendre le jeu muet"
+msgstr "Touche muet"
 
 #: src/settings_translation_file.cpp
 msgid "Mute sound"
@@ -5750,9 +5880,9 @@ msgid ""
 msgstr ""
 "Nom du générateur de terrain qui sera utilisé à la création d’un nouveau "
 "monde.\n"
-"Cela sera perdu à la création d'un monde depuis le menu principal.\n"
-"Les générateurs de terrain actuellement très instables sont : \n"
-"– Les massifs volants du générateur v7 (option inactive par défaut)."
+"La création d'un monde depuis le menu principal le remplacera.\n"
+"Les générateurs de terrain actuellement très instables sont :\n"
+"– Les terrains flottants optionnels du générateur v7 (désactivé par défaut)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5761,16 +5891,16 @@ msgid ""
 "When starting from the main menu, this is overridden."
 msgstr ""
 "Nom du joueur.\n"
-"Lors qu'un serveur est lancé, les clients se connectant avec ce nom sont "
+"Lorsqu'un serveur est lancé, les clients se connectant avec ce nom sont "
 "administrateurs.\n"
-"Lorsque vous démarrez à partir du menu principal, celui-ci est remplacé."
+"Lors du démarrage à partir du menu principal, celui-ci est remplacé."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Name of the server, to be displayed when players join and in the serverlist."
 msgstr ""
-"Nom du serveur, affiché sur liste des serveurs publics et lorsque les "
-"joueurs se connectent."
+"Nom du serveur affiché lorsque les joueurs se connectent et sur la liste des "
+"serveurs."
 
 #: src/settings_translation_file.cpp
 msgid "Near plane"
@@ -5798,7 +5928,7 @@ msgstr "Sans collision"
 
 #: src/settings_translation_file.cpp
 msgid "Noclip key"
-msgstr "Mode sans collision"
+msgstr "Touche mode sans collision"
 
 #: src/settings_translation_file.cpp
 msgid "Node highlighting"
@@ -5830,12 +5960,12 @@ msgid ""
 "'on_generated'. For many users the optimum setting may be '1'."
 msgstr ""
 "Nombre de processus « emerge » à utiliser.\n"
-"Valeur 0 : \n"
+"Valeur 0 :\n"
 "– Sélection automatique. Le nombre de processus sera le\n"
 "– « nombre de processeurs - 2 », avec un minimum de 1.\n"
-"Toute autre valeur : \n"
+"Toute autre valeur :\n"
 "– Spécifie le nombre de processus, avec un minimum de 1.\n"
-"ATTENTION : Augmenter le nombre de processus « emerge » accélère bien la\n"
+"ATTENTION : augmenter le nombre de processus « emerge » accélère bien la\n"
 "création de terrain, mais cela peut nuire à la performance du jeu en "
 "interférant\n"
 "avec d’autres processus, en particulier en mode solo et/ou lors de "
@@ -5846,14 +5976,14 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
-"Nombre d'extra-mapblocks qui peuvent être chargés par /clearobjects dans "
-"l'immédiat.\n"
-"C'est un compromis entre un transfert SQLite plafonné et la consommation "
-"mémoire\n"
-"(4096 = 100 Mo, comme règle fondamentale)."
+"Nombre de blocs supplémentaires qui peuvent être chargés par « /"
+"clearobjects » à la fois.\n"
+"C'est un compromis entre la surcharge de transaction SQLite et la "
+"consommation mémoire\n"
+"(4096 = 100 Mo, comme règle générale)."
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
@@ -5876,30 +6006,28 @@ msgid ""
 "open."
 msgstr ""
 "Ouvre le menu pause lorsque la sélection de la fenêtre est perdue. Ne met "
-"pas en pause\n"
-"si un formspec est ouvert."
+"pas en pause si un formspec est ouvert."
+
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Remplacement optionnel pour la couleur du lien web du tchat."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
-"Chemin de la police de repli.\n"
-"Si le paramètre « freetype » est activé : doit être une police TrueType.\n"
-"Si le paramètre « freetype » est désactivé : doit être une police de "
-"vecteurs bitmap ou XML.\n"
+"Chemin de la police alternative. Doit être une police TrueType.\n"
 "Cette police sera utilisée pour certaines langues ou si la police par défaut "
-"n’est pas disponible."
+"est indisponible."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Path to save screenshots at. Can be an absolute or relative path.\n"
 "The folder will be created if it doesn't already exist."
 msgstr ""
-"Chemin d'accès pour les captures d'écran (absolu ou relatif).\n"
+"Chemin pour enregistrer les captures d'écran (absolu ou relatif).\n"
 "La création du dossier sera faite si besoin."
 
 #: src/settings_translation_file.cpp
@@ -5918,28 +6046,18 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
-"Chemin vers la police par défaut.\n"
-"Si le paramètre « freetype » est activé : doit être une police TrueType.\n"
-"Si le paramètre « freetype » est désactivé : doit être une police de "
-"vecteurs bitmap ou XML.\n"
-"La police de rentrée sera utilisée si la police ne peut pas être chargée."
+"Chemin de la police par défaut. Doit être une police TrueType.\n"
+"La police alternative sera utilisée si la police ne peut pas être chargée."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
-"Chemin vers la police monospace.\n"
-"Si le paramètre « freetype » est activé : doit être une police TrueType.\n"
-"Si le paramètre « freetype » est désactivé : doit être une police de "
-"vecteurs bitmap ou XML.\n"
+"Chemin de la police monospace. Doit être une police TrueType.\n"
 "Cette police est utilisée par exemple pour la console et l’écran du "
 "profileur."
 
@@ -5953,7 +6071,7 @@ msgstr "Limite par joueur de blocs en attente à charger depuis le disque"
 
 #: src/settings_translation_file.cpp
 msgid "Per-player limit of queued blocks to generate"
-msgstr "Limite par joueur des blocs émergents à créer"
+msgstr "Limite par joueur de la file de blocs à générer"
 
 #: src/settings_translation_file.cpp
 msgid "Physics"
@@ -5961,7 +6079,7 @@ msgstr "Physique"
 
 #: src/settings_translation_file.cpp
 msgid "Pitch move key"
-msgstr "Touche de vol libre"
+msgstr "Touche vol libre"
 
 #: src/settings_translation_file.cpp
 msgid "Pitch move mode"
@@ -5969,7 +6087,7 @@ msgstr "Mode de mouvement libre"
 
 #: src/settings_translation_file.cpp
 msgid "Place key"
-msgstr "Touche pour placer"
+msgstr "Touche placer"
 
 #: src/settings_translation_file.cpp
 msgid "Place repetition interval"
@@ -5996,9 +6114,8 @@ msgid "Player versus player"
 msgstr "Joueur contre joueur"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Filtrage bilinéaire"
+msgstr "Filtrage de Poisson"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6006,15 +6123,16 @@ msgid ""
 "Note that the port field in the main menu overrides this setting."
 msgstr ""
 "Port où se connecter (UDP).\n"
-"Notez que le champ de port dans le menu principal passe outre ce réglage."
+"Noter que le champ de port dans le menu principal passe outre ce paramètre."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Prevent digging and placing from repeating when holding the mouse buttons.\n"
 "Enable this when you dig or place too often by accident."
 msgstr ""
-"Évitez de répéter lorsque vous maintenez les boutons de la souris.\n"
-"Activez cette option lorsque vous creusez ou placez trop souvent par "
+"Empêche le minage et le placement de se répéter lors du maintien des boutons "
+"de la souris.\n"
+"Activer cette option lorsque vous creusez ou placez trop souvent par "
 "accident."
 
 #: src/settings_translation_file.cpp
@@ -6035,7 +6153,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid "Privileges that players with basic_privs can grant"
 msgstr ""
-"Les privilèges que les joueurs ayant le privilège basic_privs peuvent "
+"Les privilèges que les joueurs avec le privilège « basic_privs » peuvent "
 "accorder"
 
 #: src/settings_translation_file.cpp
@@ -6044,7 +6162,7 @@ msgstr "Profileur"
 
 #: src/settings_translation_file.cpp
 msgid "Profiler toggle key"
-msgstr "Profilage"
+msgstr "Touche profilage"
 
 #: src/settings_translation_file.cpp
 msgid "Profiling"
@@ -6057,14 +6175,14 @@ msgstr "Adresse d'écoute pour Prometheus"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Adresse d'écoute pour Prometheus.\n"
-"Lorsque Minetest est compilé avec l'option ENABLE_PROMETHEUS,\n"
-"cette adresse est utilisée pour l'écoute de données pour Prometheus.\n"
-"Les données sont sur http://127.0.0.1:30000/metrics"
+"Lorsque Minetest est compilé avec l'option « ENABLE_PROMETHEUS », cette "
+"adresse est utilisée pour l'écoute de données pour Prometheus.\n"
+"Les métriques peuvent être récupérées sur http://127.0.0.1:30000/metrics"
 
 #: src/settings_translation_file.cpp
 msgid "Proportion of large caves that contain liquid."
@@ -6076,9 +6194,9 @@ msgid ""
 "Values larger than 26 will start to produce sharp cutoffs at cloud area "
 "corners."
 msgstr ""
-"Rayon de l'aire des nuages où se trouve 64 blocs carrés de nuages.\n"
-"Les valeurs plus grandes que 26 entraînent une « coupure » nette des nuages "
-"aux coins de l'aire."
+"Rayon de la zone de nuages établi en nombre de 64 blocs de nuages carrés.\n"
+"Les valeurs plus grandes que 26 entraînent une coupure nette des nuages aux "
+"coins des zones de nuages."
 
 #: src/settings_translation_file.cpp
 msgid "Raises terrain to make valleys around the rivers."
@@ -6090,7 +6208,7 @@ msgstr "Entrée aléatoire"
 
 #: src/settings_translation_file.cpp
 msgid "Range select key"
-msgstr "Distance d'affichage illimitée"
+msgstr "Touche distance d'affichage illimitée"
 
 #: src/settings_translation_file.cpp
 msgid "Recent Chat Messages"
@@ -6098,7 +6216,7 @@ msgstr "Messages de discussion récents"
 
 #: src/settings_translation_file.cpp
 msgid "Regular font path"
-msgstr "Chemin d'accès pour la police normale"
+msgstr "Chemin de la police par défaut"
 
 #: src/settings_translation_file.cpp
 msgid "Remote media"
@@ -6114,7 +6232,7 @@ msgid ""
 "Use this to stop players from being able to use color in their messages"
 msgstr ""
 "Supprime les codes couleurs venant des messages du tchat\n"
-"Utilisez cette option pour empêcher les joueurs d’utiliser la couleur dans "
+"Utiliser cette option pour empêcher les joueurs d’utiliser la couleur dans "
 "leurs messages"
 
 #: src/settings_translation_file.cpp
@@ -6139,15 +6257,15 @@ msgid ""
 "READ_PLAYERINFO: 32 (disable get_player_names call client-side)"
 msgstr ""
 "Limite l'accès de certaines fonctions côté client sur les serveurs\n"
-"Combiner les byteflags ci dessous pour restreindre les fonctionnalités "
-"client, ou mettre 0 pour laisser sans restriction : \n"
-"LOAD_CLIENT_MODS : 1 (désactive le chargement des mods client)\n"
-"CHAT_MESSAGES : 2 (désactive l'appel send_chat_message côté client)\n"
-"READ_ITEMDEFS : 4 (désactive l'appel get_item_def côté client)\n"
-"READ_NODEDEFS : 8 (désactive l'appel get_node_def côté client)\n"
-"LOOKUP_NODES_LIMIT : 16 (limite l'appel get_node côté client à "
-"csm_restriction_noderange)\n"
-"READ_PLAYERINFO : 32 (désactive l'appel get_player_names côté client)"
+"Combiner les « byteflags » ci dessous pour restreindre les fonctionnalités "
+"client, ou mettre 0 pour laisser sans restriction :\n"
+"LOAD_CLIENT_MODS : 1 (désactive le chargement des mods client)\n"
+"CHAT_MESSAGES : 2 (désactive l'appel « send_chat_message côté » client)\n"
+"READ_ITEMDEFS : 4 (désactive l'appel « get_item_def côté » client)\n"
+"READ_NODEDEFS : 8 (désactive l'appel « get_node_def » côté client)\n"
+"LOOKUP_NODES_LIMIT : 16 (limite l'appel « get_node » côté client à "
+"« csm_restriction_noderange »)\n"
+"READ_PLAYERINFO : 32 (désactive l'appel « get_player_names » côté client)"
 
 #: src/settings_translation_file.cpp
 msgid "Ridge mountain spread noise"
@@ -6155,19 +6273,19 @@ msgstr "Bruit pour l'espacement des crêtes de montagnes"
 
 #: src/settings_translation_file.cpp
 msgid "Ridge noise"
-msgstr "Bruit pour les crêtes"
+msgstr "Bruit des crêtes"
 
 #: src/settings_translation_file.cpp
 msgid "Ridge underwater noise"
-msgstr "Bruit pour les crêtes sous l'eau"
+msgstr "Bruit des crêtes sous l'eau"
 
 #: src/settings_translation_file.cpp
 msgid "Ridged mountain size noise"
-msgstr "Bruit pour la taille des crêtes de montagne"
+msgstr "Bruit de la taille des crêtes de montagnes"
 
 #: src/settings_translation_file.cpp
 msgid "Right key"
-msgstr "Droite"
+msgstr "Touche droite"
 
 #: src/settings_translation_file.cpp
 msgid "River channel depth"
@@ -6183,7 +6301,7 @@ msgstr "Profondeur des rivières"
 
 #: src/settings_translation_file.cpp
 msgid "River noise"
-msgstr "Bruit pour les rivières"
+msgstr "Bruit des rivières"
 
 #: src/settings_translation_file.cpp
 msgid "River size"
@@ -6211,12 +6329,12 @@ msgstr "Mini-carte circulaire"
 
 #: src/settings_translation_file.cpp
 msgid "Safe digging and placing"
-msgstr "Placement et minage sécurisés"
+msgstr "Minage et placement sécurisés"
 
 #: src/settings_translation_file.cpp
 msgid "Sandy beaches occur when np_beach exceeds this value."
 msgstr ""
-"Des plages de sables apparaissent lorsque np_beach dépasse cette valeur."
+"Des plages de sables apparaissent lorsque « np_beach » dépasse cette valeur."
 
 #: src/settings_translation_file.cpp
 msgid "Save the map received by the client on disk."
@@ -6225,11 +6343,11 @@ msgstr "Sauvegarde le monde du serveur sur le disque dur du client."
 #: src/settings_translation_file.cpp
 msgid "Save window size automatically when modified."
 msgstr ""
-"Sauvegarder automatiquement la taille de la fenêtre quand elle est modifiée."
+"Sauvegarde automatiquement la taille de la fenêtre quand elle est modifiée."
 
 #: src/settings_translation_file.cpp
 msgid "Saving map received from server"
-msgstr "Sauvegarder le monde du serveur"
+msgstr "Sauvegarde de la carte reçue du serveur"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6239,13 +6357,11 @@ msgid ""
 "pixels when scaling down, at the cost of blurring some\n"
 "edge pixels when images are scaled by non-integer sizes."
 msgstr ""
-"Met à l'échelle l'interface par une valeur spécifiée par l'utilisateur,\n"
-"à l'aide d'un filtre au plus proche avec anticrénelage.\n"
+"Met à l'échelle l'interface par une valeur spécifiée par l'utilisateur, à "
+"l'aide d'un filtre au plus proche voisin avec anticrénelage.\n"
 "Cela va lisser certains bords grossiers, et mélanger les pixels en réduisant "
-"l'échelle\n"
-"au détriment d'un effet de flou sur des pixels en bordure quand les images "
-"sont\n"
-"mises à l'échelle par des valeurs fractionnelles."
+"l'échelle au détriment d'un effet de flou sur des pixels en bordure quand "
+"les images sont mises à l'échelle par des valeurs fractionnelles."
 
 #: src/settings_translation_file.cpp
 msgid "Screen height"
@@ -6275,21 +6391,21 @@ msgid ""
 msgstr ""
 "Qualité de capture d'écran. Utilisé uniquement pour le format JPEG.\n"
 "1 signifie mauvaise qualité ; 100 signifie la meilleure qualité.\n"
-"Utilisez 0 pour la qualité par défaut."
+"Utiliser 0 pour la qualité par défaut."
 
 #: src/settings_translation_file.cpp
 msgid "Seabed noise"
-msgstr "Bruit pour les fonds marins"
+msgstr "Bruit des fonds marins"
 
 #: src/settings_translation_file.cpp
 msgid "Second of 4 2D noises that together define hill/mountain range height."
 msgstr ""
-"Deuxième des 4 bruits 2D qui définissent ensemble la taille des collines et "
-"montagnes."
+"Deuxième des 4 bruits 2D qui définissent ensemble la hauteur des collines et "
+"des montagnes."
 
 #: src/settings_translation_file.cpp
 msgid "Second of two 3D noises that together define tunnels."
-msgstr "Deuxième des 2 bruits 3D qui définissent ensemble les tunnels."
+msgstr "Deuxième des deux bruits 3D qui définissent ensemble les tunnels."
 
 #: src/settings_translation_file.cpp
 msgid "Security"
@@ -6379,15 +6495,15 @@ msgstr "Port du serveur"
 
 #: src/settings_translation_file.cpp
 msgid "Server side occlusion culling"
-msgstr "Tests d'occultation côté serveur"
+msgstr "Détermination des blocs invisibles côté serveur"
 
 #: src/settings_translation_file.cpp
 msgid "Serverlist URL"
-msgstr "URL de la liste des serveurs publics"
+msgstr "URL de la liste des serveurs"
 
 #: src/settings_translation_file.cpp
 msgid "Serverlist file"
-msgstr "Fichier des serveurs publics"
+msgstr "Fichier de la liste des serveurs"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6400,7 +6516,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid "Set the maximum character length of a chat message sent by clients."
 msgstr ""
-"Définir la longueur maximale de caractères d'un message de discussion envoyé "
+"Définit la longueur maximale de caractères d'un message de discussion envoyé "
 "par les clients."
 
 #: src/settings_translation_file.cpp
@@ -6408,36 +6524,37 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Définit la force de l'ombre.\n"
+"Une valeur plus faible signifie des ombres plus claires, une valeur plus "
+"élevée signifie des ombres plus sombres."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Définit la taille du rayon de l'ombre douce.\n"
+"Les valeurs les plus faibles signifient des ombres plus nettes, les valeurs "
+"les plus élevées des ombres plus douces.\n"
+"Valeur minimale : 1,0 ; valeur maximale : 10,0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Définit l'inclinaison de l'orbite du soleil / lune en degrés.\n"
+"La valeur de 0 signifie aucune inclinaison / orbite verticale.\n"
+"Valeur minimale : 0,0 ; valeur maximale : 60,0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Mettre sur « Activé » active les feuilles ondulantes.\n"
+"Mettre sur « Activé » active le « Shadow Mapping ».\n"
 "Nécessite les shaders pour être activé."
 
 #: src/settings_translation_file.cpp
@@ -6470,6 +6587,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Définit la qualité de la texture de l'ombre sur 32 bits.\n"
+"Si désactivé, une texture de 16 bits sera utilisée.\n"
+"Cela peut causer beaucoup plus d'artefacts sur l'ombre."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6487,22 +6607,21 @@ msgstr ""
 "Fonctionne seulement avec OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Qualité des captures d'écran"
+msgstr "Qualité du filtre d’ombre"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
 msgstr ""
+"Distance maximale de la carte des ombres en nœuds pour le rendu des ombres"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Texture de la carte des ombres en 32 bits"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Taille minimale des textures"
+msgstr "Taille de la texture de la carte des ombres"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6514,7 +6633,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Force de l'ombre"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6537,7 +6656,7 @@ msgstr ""
 "Un redémarrage est nécessaire après cette modification."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr "Afficher l'arrière-plan des badges par défaut"
 
 #: src/settings_translation_file.cpp
@@ -6553,9 +6672,9 @@ msgid ""
 "Altering this value is for special usage, leaving it unchanged is\n"
 "recommended."
 msgstr ""
-"Taille des mapchunks générés à la création de terrain, définie en mapblocks "
-"(16 nœuds).\n"
-"ATTENTION ! : Il n’y a aucun avantage, et plusieurs dangers, à augmenter "
+"Taille des tranches de carte générés à la création de terrain, établie en "
+"blocs de carte (16 nœuds).\n"
+"ATTENTION ! : Il n’y a aucun avantage, et plusieurs dangers, à augmenter "
 "cette valeur au-dessus de 5.\n"
 "Réduire cette valeur augmente la densité de cavernes et de donjons.\n"
 "La modification de cette valeur est réservée à un usage spécial. Il est "
@@ -6567,13 +6686,13 @@ msgid ""
 "increase the cache hit %, reducing the data being copied from the main\n"
 "thread, thus reducing jitter."
 msgstr ""
-"Taille du cache de MapBlocks du générateur de maillage. Augmenter\n"
-"ceci augmente le % d'interception du cache et réduit la copie de données\n"
-"dans le fil principal, réduisant les tremblements."
+"Taille du cache de blocs de carte du générateur de maillage. Augmenter ceci "
+"augmente le % d'interception du cache et réduit la copie de données dans le "
+"fil principal, réduisant les tremblements."
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Inclinaison de l'orbite du corps du ciel"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6595,7 +6714,8 @@ msgstr "Nombre minimal de petites grottes"
 #: src/settings_translation_file.cpp
 msgid "Small-scale humidity variation for blending biomes on borders."
 msgstr ""
-"Variation d'humidité de petite échelle pour la transition entre les biomes."
+"Variation de l'humidité de petite échelle pour la transition entre les "
+"biomes."
 
 #: src/settings_translation_file.cpp
 msgid "Small-scale temperature variation for blending biomes on borders."
@@ -6612,7 +6732,8 @@ msgid ""
 "Smooths camera when looking around. Also called look or mouse smoothing.\n"
 "Useful for recording videos."
 msgstr ""
-"Lisse les mouvement de la caméra en se déplaçant et en regardant autour.\n"
+"Lisse les mouvements de la caméra en se déplaçant et en regardant autour. "
+"Également appelé « look smoothing » ou « mouse smoothing ».\n"
 "Utile pour enregistrer des vidéos."
 
 #: src/settings_translation_file.cpp
@@ -6625,20 +6746,19 @@ msgstr "Lisse la rotation de la caméra. 0 pour désactiver."
 
 #: src/settings_translation_file.cpp
 msgid "Sneak key"
-msgstr "Déplacement lent"
+msgstr "Touche déplacement lent"
 
 #: src/settings_translation_file.cpp
 msgid "Sneaking speed"
-msgstr "Vitesse d'accroupissement"
+msgstr "Vitesse de déplacement lent"
 
 #: src/settings_translation_file.cpp
 msgid "Sneaking speed, in nodes per second."
-msgstr "Vitesse furtive, en blocs par seconde."
+msgstr "Vitesse de déplacement lent, en nœuds par seconde."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Opacité de l'ombre de la police"
+msgstr "Rayon de l'ombre douce"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6669,6 +6789,19 @@ msgstr ""
 "Les mods ou les parties peuvent fixer explicitement une pile pour certains "
 "items."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Réparti une mise à jour complète de la carte des ombres sur un nombre donné "
+"d'images.\n"
+"Des valeurs plus élevées peuvent rendre les ombres plus lentes, des valeurs "
+"plus faibles consommeront plus de ressources.\n"
+"Valeur minimale : 1 ; valeur maximale : 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6685,15 +6818,15 @@ msgstr "Point d'apparition statique"
 
 #: src/settings_translation_file.cpp
 msgid "Steepness noise"
-msgstr "Bruit pour les pentes"
+msgstr "Bruit des pentes"
 
 #: src/settings_translation_file.cpp
 msgid "Step mountain size noise"
-msgstr "Bruit pour la taille des montagnes en escalier"
+msgstr "Bruit de la taille des montagnes en escalier"
 
 #: src/settings_translation_file.cpp
 msgid "Step mountain spread noise"
-msgstr "Bruit pour l’étalement des montagnes en escalier"
+msgstr "Bruit d'étalement des montagnes en escalier"
 
 #: src/settings_translation_file.cpp
 msgid "Strength of 3D mode parallax."
@@ -6706,8 +6839,8 @@ msgid ""
 "curve that is boosted in brightness."
 msgstr ""
 "Niveau d'amplification de la courbure de la lumière.\n"
-"Les trois paramètres « d'amplification » définissent un intervalle\n"
-"de la courbe de lumière pour lequel la luminosité est amplifiée."
+"Les trois paramètres « d'amplification » définissent un intervalle de la "
+"courbe de lumière pour lequel la luminosité est amplifiée."
 
 #: src/settings_translation_file.cpp
 msgid "Strict protocol checking"
@@ -6715,7 +6848,7 @@ msgstr "Vérification stricte du protocole"
 
 #: src/settings_translation_file.cpp
 msgid "Strip color codes"
-msgstr "Echapper les codes de couleur"
+msgstr "Supprimer les codes couleurs"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6730,18 +6863,18 @@ msgid ""
 "server-intensive extreme water flow and to avoid vast flooding of the\n"
 "world surface below."
 msgstr ""
-"Niveau de la surface de l'eau (facultative) placée sur une couche solide de "
-"terre suspendue.\n"
+"Niveau de la surface de l'eau (optionnel) placée sur une couche solide de "
+"terrain flottant.\n"
 "L'eau est désactivée par défaut et ne sera placée que si cette valeur est "
-"fixée à plus de « mgv7_floatland_ymax » - « mgv7_floatland_taper » (début de "
-"l’effilage du haut).\n"
+"définie à plus de « mgv7_floatland_ymax » - « mgv7_floatland_taper » (début "
+"de l’effilage du haut).\n"
 "***ATTENTION, DANGER POTENTIEL AU MONDES ET AUX PERFORMANCES DES "
 "SERVEURS*** :\n"
-"Lorsque le placement de l'eau est activé, les île volantes doivent être "
-"configurées avec une couche solide en mettant « mgv7_floatland_density » à "
-"2,0 (ou autre valeur dépendante de « mgv7_np_floatland »), pour éviter les "
-"chutes d'eaux énormes qui surchargent les serveurs et pourraient inonder les "
-"terres en dessous."
+"Lorsque le placement de l'eau est activé, les terrains flottants doivent "
+"être configurés et vérifiés pour être une couche solide en mettant "
+"« mgv7_floatland_density » à 2,0 (ou autre valeur dépendante de "
+"« mgv7_np_floatland »), pour éviter les chutes d'eaux énormes qui "
+"surchargent les serveurs et pourraient inonder les terres en dessous."
 
 #: src/settings_translation_file.cpp
 msgid "Synchronous SQLite"
@@ -6753,11 +6886,11 @@ msgstr "Variation de température pour les biomes."
 
 #: src/settings_translation_file.cpp
 msgid "Terrain alternative noise"
-msgstr "Bruit alternatif pour le terrain"
+msgstr "Bruit alternatif de terrain"
 
 #: src/settings_translation_file.cpp
 msgid "Terrain base noise"
-msgstr "Bruit pour le terrain de base"
+msgstr "Bruit de terrain de base"
 
 #: src/settings_translation_file.cpp
 msgid "Terrain height"
@@ -6765,11 +6898,11 @@ msgstr "Hauteur du terrain"
 
 #: src/settings_translation_file.cpp
 msgid "Terrain higher noise"
-msgstr "Bruit pour la hauteur du terrain"
+msgstr "Bruit de hauteur du terrain"
 
 #: src/settings_translation_file.cpp
 msgid "Terrain noise"
-msgstr "Bruit pour le terrain"
+msgstr "Bruit de terrain"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6778,7 +6911,7 @@ msgid ""
 "Adjust towards 0.0 for a larger proportion."
 msgstr ""
 "Seuil du bruit de relief pour les collines.\n"
-"Contrôle la proportion sur la superficie d'un monde recouvert de collines.\n"
+"Contrôle la proportion sur la zone d'un monde recouvert de collines.\n"
 "Ajuster vers 0,0 pour une plus grande proportion."
 
 #: src/settings_translation_file.cpp
@@ -6788,12 +6921,12 @@ msgid ""
 "Adjust towards 0.0 for a larger proportion."
 msgstr ""
 "Seuil du bruit de relief pour les lacs.\n"
-"Contrôle la proportion sur la superficie d'un monde recouvert de lacs.\n"
+"Contrôle la proportion sur la zone d'un monde recouvert de lacs.\n"
 "Ajuster vers 0,0 pour une plus grande proportion."
 
 #: src/settings_translation_file.cpp
 msgid "Terrain persistence noise"
-msgstr "Bruit du terrain persistant"
+msgstr "Bruit de persistance du terrain"
 
 #: src/settings_translation_file.cpp
 msgid "Texture path"
@@ -6803,8 +6936,12 @@ msgstr "Chemin des textures"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Taille de la texture pour le rendu de la carte des ombres.\n"
+"Il doit s'agir d'une puissance de deux.\n"
+"Les nombres plus grands créent de meilleures ombres, mais ils sont aussi "
+"plus coûteux."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6816,19 +6953,20 @@ msgid ""
 "that is considered EXPERIMENTAL and may not work properly."
 msgstr ""
 "Les textures sur un nœud peuvent être alignées soit sur le nœud, soit sur le "
-"monde. L'ancien mode convient mieux aux machines, aux meubles, etc. ce "
-"dernier rend les escaliers et les microblocs mieux adaptés à "
-"l'environnement. Cependant, comme cette possibilité est nouvelle, elle ne "
-"peut donc pas être utilisée par les anciens serveurs, cette option permet de "
-"l'appliquer pour certains types de nœuds. Notez cependant que c'est "
-"considéré comme EXPÉRIMENTAL et peut ne pas fonctionner correctement."
+"monde. Le premier mode convient mieux aux choses comme des machines, des "
+"meubles, etc., tandis que le second rend les escaliers et les microblocs "
+"mieux adaptés à l'environnement. Cependant, comme cette possibilité est "
+"nouvelle, elle ne peut donc pas être utilisée par les anciens serveurs, "
+"cette option permet de l'appliquer pour certains types de nœuds. Noter "
+"cependant que c'est considéré comme EXPÉRIMENTAL et peut ne pas fonctionner "
+"correctement."
 
 #: src/settings_translation_file.cpp
 msgid "The URL for the content repository"
 msgstr "L'URL du dépôt de contenu en ligne"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "La zone morte de la manette"
 
 #: src/settings_translation_file.cpp
@@ -6836,8 +6974,8 @@ msgid ""
 "The default format in which profiles are being saved,\n"
 "when calling `/profiler save [format]` without format."
 msgstr ""
-"Le format par défaut dans lequel les profils seront sauvegardés,\n"
-"lorsque la commande `/profiler save [format]` est entrée sans format."
+"Le format par défaut dans lequel les profils sont enregistrés, lors de "
+"l'appel de « /profiler save [format] » sans format."
 
 #: src/settings_translation_file.cpp
 msgid "The depth of dirt or other biome filler node."
@@ -6886,7 +7024,7 @@ msgid ""
 "See /privs in game for a full list on your server and mod configuration."
 msgstr ""
 "Les privilèges que les nouveaux joueurs obtiennent automatiquement.\n"
-"Entrer /privs dans le jeu pour voir une liste complète des privilèges."
+"Entrer « /privs » dans le jeu pour voir une liste complète des privilèges."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6899,15 +7037,14 @@ msgid ""
 "This should be configured together with active_object_send_range_blocks."
 msgstr ""
 "Le rayon du volume de blocs autour de chaque joueur soumis au bloc actif, "
-"définie en mapblocks (16 nœuds).\n"
+"établi en blocs de carte (16 nœuds).\n"
 "Dans les blocs actifs, les objets sont chargés et les « ABMs » sont "
 "exécutés.\n"
 "C'est également la distance minimale dans laquelle les objets actifs (mobs) "
 "sont conservés.\n"
-"Ceci devrait être configuré avec active_object_send_range_blocks."
+"Ceci devrait être configuré avec « active_object_send_range_blocks »."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6916,9 +7053,9 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Le moteur de rendu utilisé par Irrlicht.\n"
+"Le moteur de rendu.\n"
 "Un redémarrage est nécessaire après cette modification.\n"
-"Remarque : Sur Android, restez avec OGLES1 en cas de doute ! Autrement, "
+"Remarque : Sur Android, rester avec OGLES1 en cas de doute ! Autrement, "
 "l'application peut ne pas démarrer.\n"
 "Sur les autres plateformes, OpenGL est recommandé.\n"
 "Les shaders sont pris en charge par OpenGL (ordinateur de bureau uniquement) "
@@ -6927,7 +7064,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Sensibilité des axes de la manette pour déplacer la vue en jeu autour du "
 "tronc."
@@ -6999,14 +7136,14 @@ msgstr ""
 msgid "Third of 4 2D noises that together define hill/mountain range height."
 msgstr ""
 "Le troisième des 4 bruits 2D qui définissent ensemble la hauteur des "
-"collines et montagnes."
+"collines et des montagnes."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Time in seconds for item entity (dropped items) to live.\n"
 "Setting it to -1 disables the feature."
 msgstr ""
-"Durée en secondes pendant laquelle les objets jetés sont présents.\n"
+"Temps en secondes pour les entités objets (objets lâchés) à exister.\n"
 "Définir à -1 pour désactiver cette fonctionnalité."
 
 #: src/settings_translation_file.cpp
@@ -7026,8 +7163,8 @@ msgstr "Vitesse du temps"
 #: src/settings_translation_file.cpp
 msgid "Timeout for client to remove unused map data from memory."
 msgstr ""
-"Délai pendant lequel le client supprime les données de la carte de sa "
-"mémoire."
+"Délai d'interruption pour le client pour supprimer les données de carte "
+"inutilisées de la mémoire."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7036,26 +7173,30 @@ msgid ""
 "This determines how long they are slowed down after placing or removing a "
 "node."
 msgstr ""
-"Pour réduire le lag, le transfert des blocs est ralenti quand un joueur "
+"Pour réduire le décalage, le transfert des blocs est ralenti quand un joueur "
 "construit quelque chose.\n"
 "Cela détermine la durée du ralentissement après placement ou destruction "
 "d'un nœud."
 
 #: src/settings_translation_file.cpp
 msgid "Toggle camera mode key"
-msgstr "Basculement en mode caméra"
+msgstr "Touche basculer en mode caméra"
 
 #: src/settings_translation_file.cpp
 msgid "Tooltip delay"
-msgstr "Délais d'apparition des infobulles"
+msgstr "Délai d'apparition des infobulles"
 
 #: src/settings_translation_file.cpp
 msgid "Touch screen threshold"
 msgstr "Sensibilité de l'écran tactile"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "Compromis pour la performance"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
-msgstr "Bruit pour les arbres"
+msgstr "Bruit des arbres"
 
 #: src/settings_translation_file.cpp
 msgid "Trilinear filtering"
@@ -7078,11 +7219,12 @@ msgstr "Mods sécurisés"
 
 #: src/settings_translation_file.cpp
 msgid "URL to the server list displayed in the Multiplayer Tab."
-msgstr "URL de la liste des serveurs affichée dans l'onglet multijoueur."
+msgstr ""
+"URL de la liste des serveurs affichée dans l'onglet « Rejoindre une partie »."
 
 #: src/settings_translation_file.cpp
 msgid "Undersampling"
-msgstr "Sous-échantillonage"
+msgstr "Sous-échantillonnage"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7092,11 +7234,11 @@ msgid ""
 "image.\n"
 "Higher values result in a less detailed image."
 msgstr ""
-"Le sous-échantillonage ressemble à l'utilisation d'une résolution d'écran "
-"inférieure,\n"
-"mais il ne s'applique qu'au rendu 3D, gardant l'interface usager intacte.\n"
-"Cela peut donner lieu à un bonus de performance conséquent, au détriment de "
-"la qualité d'image.\n"
+"Le sous-échantillonnage ressemble à l'utilisation d'une résolution d'écran "
+"inférieure, mais il ne s'applique qu'au rendu 3D, gardant l'interface "
+"intacte.\n"
+"Cela doit donner un bonus de performance conséquent, au détriment de la "
+"qualité d'image.\n"
 "Les valeurs plus élevées réduisent la qualité du détail des images."
 
 #: src/settings_translation_file.cpp
@@ -7105,7 +7247,7 @@ msgstr "Distance de transfert du joueur illimitée"
 
 #: src/settings_translation_file.cpp
 msgid "Unload unused server data"
-msgstr "Purger les données de serveur inutiles"
+msgstr "Décharger les données de serveur inutilisées"
 
 #: src/settings_translation_file.cpp
 msgid "Upper Y limit of dungeons."
@@ -7113,7 +7255,7 @@ msgstr "Limite haute Y des donjons."
 
 #: src/settings_translation_file.cpp
 msgid "Upper Y limit of floatlands."
-msgstr "Limite en Y des îles volantes."
+msgstr "Limite haute Y des terrains flottants."
 
 #: src/settings_translation_file.cpp
 msgid "Use 3D cloud look instead of flat."
@@ -7136,13 +7278,13 @@ msgstr "Utilisation du filtrage bilinéaire."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
-"Utilisez le mappage MIP pour mettre à l'échelle les textures. Peut augmenter "
-"légèrement les performances, surtout si vous utilisez un pack de textures "
-"haute résolution.\n"
+"Utilise le mip-mapping pour mettre à l'échelle les textures.\n"
+"Peut augmenter légèrement les performances, surtout lors de l'utilisation "
+"d'un pack de textures haute résolution.\n"
 "La réduction d'échelle gamma correcte n'est pas prise en charge."
 
 #: src/settings_translation_file.cpp
@@ -7157,9 +7299,9 @@ msgid ""
 msgstr ""
 "Utilise l'anticrénelage multi-échantillons (MSAA) pour lisser les bords des "
 "blocs.\n"
-"Cet algorithme lisse la vue 3D tout en conservant l'image nette,\n"
-"mais cela ne concerne pas la partie interne des textures\n"
-"(ce qui est particulièrement visible avec des textures transparentes).\n"
+"Cet algorithme lisse la vue 3D tout en conservant l'image nette, mais cela "
+"ne concerne pas la partie interne des textures (ce qui est particulièrement "
+"visible avec des textures transparentes).\n"
 "Des espaces visibles apparaissent entre les blocs lorsque les shaders sont "
 "désactivés.\n"
 "Si définie à 0, MSAA est désactivé.\n"
@@ -7183,7 +7325,7 @@ msgstr "Profondeur des vallées"
 
 #: src/settings_translation_file.cpp
 msgid "Valley fill"
-msgstr "Comblement de vallée"
+msgstr "Comblement des vallées"
 
 #: src/settings_translation_file.cpp
 msgid "Valley profile"
@@ -7203,7 +7345,7 @@ msgstr "Variation de la hauteur maximale des montagnes (en blocs)."
 
 #: src/settings_translation_file.cpp
 msgid "Variation of number of caves."
-msgstr "Variation du nombre de cavernes."
+msgstr "Variation du nombre de grottes."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7252,24 +7394,23 @@ msgstr "Distance d'affichage en blocs."
 
 #: src/settings_translation_file.cpp
 msgid "View range decrease key"
-msgstr "Réduire la distance d'affichage"
+msgstr "Touche réduire la distance d'affichage"
 
 #: src/settings_translation_file.cpp
 msgid "View range increase key"
-msgstr "Augmenter la distance d'affichage"
+msgstr "Touche augmenter la distance d'affichage"
 
 #: src/settings_translation_file.cpp
 msgid "View zoom key"
-msgstr "Touche de vue du zoom"
+msgstr "Touche zoomer"
 
 #: src/settings_translation_file.cpp
 msgid "Viewing range"
 msgstr "Plage de visualisation"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Manette virtuelle déclenche le bouton aux"
+msgstr "Manette virtuelle déclenche le bouton Aux1"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7332,11 +7473,11 @@ msgstr "Liquides ondulants"
 
 #: src/settings_translation_file.cpp
 msgid "Waving liquids wave height"
-msgstr "Hauteur des vagues"
+msgstr "Hauteur des vagues des liquides ondulants"
 
 #: src/settings_translation_file.cpp
 msgid "Waving liquids wave speed"
-msgstr "Vitesse de mouvement des liquides"
+msgstr "Vitesse de mouvement des liquides ondulants"
 
 #: src/settings_translation_file.cpp
 msgid "Waving liquids wavelength"
@@ -7346,15 +7487,19 @@ msgstr "Longueur d'onde des liquides ondulants"
 msgid "Waving plants"
 msgstr "Plantes ondulantes"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Couleur du lien web"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
 "filtered in software, but some images are generated directly\n"
 "to hardware (e.g. render-to-texture for nodes in inventory)."
 msgstr ""
-"Quand gui_scaling_filter est activé, tous les images du GUI sont filtrées "
-"par le logiciel, mais certaines sont générées directement par le matériel "
-"(ex. : textures des blocs dans l'inventaire)."
+"Quand « gui_scaling_filter » est activé, tous les images du GUI sont "
+"filtrées par le logiciel, mais certaines sont générées directement par le "
+"matériel (ex. : textures des blocs dans l'inventaire)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7363,20 +7508,19 @@ msgid ""
 "to the old scaling method, for video drivers that don't\n"
 "properly support downloading textures back from hardware."
 msgstr ""
-"Quand gui_scaling_filter_txr2img est activé, copier les images du matériel "
-"au logiciel pour mise à l'échelle.\n"
+"Quand « gui_scaling_filter_txr2img » est activé, copier les images du "
+"matériel au logiciel pour mise à l'échelle.\n"
 "Si désactivé, l'ancienne méthode de mise à l'échelle est utilisée, pour les "
 "pilotes vidéos qui ne supportent pas le chargement des textures depuis le "
 "matériel."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7386,26 +7530,15 @@ msgstr ""
 "agrandies avec l'interpolation du plus proche voisin pour garder des pixels "
 "moins floues. Ceci détermine la taille de la texture minimale pour les "
 "textures agrandies ; les valeurs plus hautes rendent plus détaillées, mais "
-"nécessitent plus de mémoire. Les puissances de 2 sont recommandées. Définir "
-"une valeur supérieure à 1 peut ne pas avoir d'effet visible sauf si le "
-"filtrage bilinéaire/trilinéaire/anisotrope est activé.\n"
-"Ceci est également utilisée comme taille de texture de nœud par défaut pour "
-"l'agrandissement des textures basé sur le monde."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Détermine l'utilisation des polices Freetype. Nécessite une compilation avec "
-"le support Freetype.\n"
-"Si désactivée, des polices bitmap et en vecteurs XML seront utilisé en "
-"remplacement."
+"nécessitent plus de mémoire. Les puissances de 2 sont recommandées. Ce "
+"paramètre est appliqué uniquement si le filtrage bilinéaire/trilinéaire/"
+"anisotrope est activé.\n"
+"Ceci est également utilisée comme taille de texture de nœud de base pour "
+"l'agrandissement automatique des textures alignées sur le monde."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 "Si l'arrière-plan des badges doit être affiché par défaut.\n"
@@ -7413,7 +7546,9 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Whether node texture animations should be desynchronized per mapblock."
-msgstr "Détermine la désynchronisation des textures animées par mapblock."
+msgstr ""
+"Détermine la désynchronisation des animations de texture de nœud par bloc de "
+"carte."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7421,7 +7556,7 @@ msgid ""
 "Deprecated, use the setting player_transfer_distance instead."
 msgstr ""
 "Détermine l'exposition illimitée des noms de joueurs aux autres clients.\n"
-"Obsolète : utiliser l'option player_transfer_distance à la place."
+"Obsolète : utiliser le paramètre « player_transfer_distance » à la place."
 
 #: src/settings_translation_file.cpp
 msgid "Whether to allow players to damage and kill each other."
@@ -7433,7 +7568,8 @@ msgid ""
 "Set this to true if your server is set up to restart automatically."
 msgstr ""
 "S’il faut demander aux clients de se reconnecter après un crash (Lua).\n"
-"Activez-le si votre serveur est paramétré pour redémarrer automatiquement."
+"Définir sur Activer si le serveur est paramétré pour redémarrer "
+"automatiquement."
 
 #: src/settings_translation_file.cpp
 msgid "Whether to fog out the end of the visible area."
@@ -7446,23 +7582,23 @@ msgid ""
 "In-game, you can toggle the mute state with the mute key or by using the\n"
 "pause menu."
 msgstr ""
-"S'il faut mettre les sons en sourdine. Vous pouvez désactiver les sons à "
-"tout moment, sauf si le système de sonorisation est désactivé "
-"(enable_sound=false).\n"
-"Dans le jeu, vous pouvez passer en mode silencieux avec la touche de mise en "
-"sourdine ou en utilisant le menu pause."
+"S'il faut couper le son. Vous pouvez réactiver le son à tout moment, sauf si "
+"le système audio est désactivé (« enable_sound=false »).\n"
+"Dans le jeu, vous pouvez basculer l'état du son avec la touche « Muet » ou "
+"en utilisant le menu pause."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Whether to show the client debug info (has the same effect as hitting F5)."
 msgstr ""
-"Détermine la visibilité des infos de débogage du client (même effet que "
-"taper F5)."
+"Détermine la visibilité des informations de débogage du client (même effet "
+"que taper F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Composant de largeur de la taille initiale de la fenêtre."
+msgstr ""
+"Composant de largeur de la taille initiale de la fenêtre. Ignoré en mode "
+"plein écran."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7474,9 +7610,9 @@ msgid ""
 "background.\n"
 "Contains the same information as the file debug.txt (default name)."
 msgstr ""
-"Systèmes Windows seulement : démarrer Minetest avec la fenêtre de commandes\n"
-"en arrière-plan. Contient les mêmes informations que dans debug.txt (nom par "
-"défaut)."
+"Systèmes Windows seulement : démarrer Minetest avec la fenêtre de ligne de "
+"commande en arrière-plan. Contient les mêmes informations que le fichier "
+"« debug.txt » (nom par défaut)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7500,15 +7636,12 @@ msgid ""
 "Warning: This option is EXPERIMENTAL!"
 msgstr ""
 "Les textures alignées sur le monde peuvent être mises à l'échelle pour "
-"couvrir plusieurs nœuds. Cependant,\n"
-"le serveur peut ne pas envoyer l'échelle que vous voulez, surtout si vous "
-"utilisez\n"
-"un pack de textures spécialement conçu ; avec cette option, le client "
-"essaie\n"
-"de déterminer l'échelle automatiquement en fonction de la taille de la "
-"texture.\n"
-"Voir aussi texture_min_size.\n"
-"Avertissement : Cette option est EXPÉRIMENTALE !"
+"couvrir plusieurs nœuds. Cependant, le serveur peut ne pas envoyer l'échelle "
+"que vous voulez, surtout si vous utilisez un pack de textures spécialement "
+"conçu ; avec cette option, le client essaie de déterminer l'échelle "
+"automatiquement en fonction de la taille de la texture.\n"
+"Voir aussi « texture_min_size ».\n"
+"Avertissement : cette option est EXPÉRIMENTALE !"
 
 #: src/settings_translation_file.cpp
 msgid "World-aligned textures mode"
@@ -7528,12 +7661,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Y of upper limit of large caves."
-msgstr ""
-"Coordonnée Y de la limite supérieure des grandes grottes pseudo-aléatoires."
+msgstr "Limite haute Y des grandes grottes."
 
 #: src/settings_translation_file.cpp
 msgid "Y-distance over which caverns expand to full size."
-msgstr "La distance Y jusqu'à laquelle la caverne peut s'étendre."
+msgstr ""
+"La distance Y jusqu'à laquelle les cavernes s'étendent à leur taille "
+"maximale."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7542,77 +7676,50 @@ msgid ""
 "For a solid floatland layer, this controls the height of hills/mountains.\n"
 "Must be less than or equal to half the distance between the Y limits."
 msgstr ""
-"Hauteur-Y à laquelle les îles volantes commence à rétrécir.\n"
+"Hauteur-Y à laquelle les terrains flottants commencent à rétrécir.\n"
 "L'effilage comment à cette distance de la limite en Y.\n"
-"Pour une courche solide de terre suspendue, ceci contrôle la hauteur des "
+"Pour une couche solide de terrain flottant, ceci contrôle la hauteur des "
 "montagnes.\n"
 "Doit être égale ou moindre à la moitié de la distance entre les limites Y."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of average terrain surface."
-msgstr "Hauteur (Y) moyenne de la surface du terrain."
+msgstr "Limite moyenne Y de la surface du terrain."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of cavern upper limit."
-msgstr "Limite haute de génération des cavernes."
+msgstr "Limite haute de génération des cavernes."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of higher terrain that creates cliffs."
-msgstr "Hauteur Y du plus haut terrain qui crée des falaises."
+msgstr "Limite Y du plus haut terrain qui crée des falaises."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of lower terrain and seabed."
-msgstr "Hauteur Y du plus bas terrain et des fonds marins."
+msgstr "Limite Y du plus bas terrain et des fonds marins."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of seabed."
-msgstr "Hauteur (Y) du fond marin."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Niveau de compression Zlib à utiliser lors de la sauvegarde des mapblocks "
-"sur le disque.\n"
-"-1 - niveau de compression de Zlib par défaut\n"
-"0 - aucune compression, le plus rapide\n"
-"9 - meilleure compression, le plus lent\n"
-"(les niveaux 1–3 utilisent la méthode « rapide », 4–9 utilisent la méthode "
-"normale)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Niveau de compression Zlib à utiliser lors de l'envoi des mapblocks au "
-"client.\n"
-"-1 - niveau de compression de Zlib par défaut\n"
-"0 - aucune compression, le plus rapide\n"
-"9 - meilleure compression, le plus lent\n"
-"(les niveaux 1–3 utilisent la méthode « rapide », 4–9 utilisent la méthode "
-"normale)"
+msgstr "Limite Y du fond marin."
 
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
-msgstr "Délais d'interruption de cURL lors d'un téléchargement de fichier"
+msgstr "Délai d'interruption de cURL lors d'un téléchargement de fichier"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "Délais d'interruption de cURL"
+msgstr "Délai d'interruption interactive de cURL"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "Limite parallèle de cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "– Mode créatif : "
+
+#~ msgid "- Damage: "
+#~ msgstr "– Dégâts : "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7786,6 +7893,9 @@ msgstr "Limite parallèle de cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Taille de police secondaire au point (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Polices Freetype"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Bits par pixel en mode plein écran"
 
@@ -7804,6 +7914,9 @@ msgstr "Limite parallèle de cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "Support IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Installation : fichier : « $1 »"
+
 #~ msgid "Lava depth"
 #~ msgstr "Profondeur de lave"
 
@@ -7908,6 +8021,17 @@ msgstr "Limite parallèle de cURL"
 #~ msgid "Select Package File:"
 #~ msgstr "Sélectionner le fichier du mod :"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "Définit le temps de mise à jour des ombres.\n"
+#~ "Une valeur plus faible signifie que les ombres et les mises à jour de la "
+#~ "carte sont plus rapides, mais cela consomme plus de ressources.\n"
+#~ "Valeur minimale 0,001 seconde et maximale 0,2 seconde."
+
 #~ msgid "Shadow limit"
 #~ msgstr "Limite des ombres"
 
@@ -7936,6 +8060,9 @@ msgstr "Limite parallèle de cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Cette police sera utilisée pour certaines langues."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Pour activer les shaders, le pilote OpenGL doit être utilisé."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Mode cinématique"
 
@@ -7959,6 +8086,16 @@ msgstr "Limite parallèle de cURL"
 #~ msgid "Waving water"
 #~ msgstr "Vagues"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Détermine l'utilisation des polices Freetype. Nécessite une compilation "
+#~ "avec le support Freetype.\n"
+#~ "Si désactivée, des polices bitmap et en vecteurs XML seront utilisé en "
+#~ "remplacement."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Si les donjons font parfois saillie du terrain."
 
@@ -7976,5 +8113,8 @@ msgstr "Limite parallèle de cURL"
 #~ msgid "Yes"
 #~ msgstr "Oui"
 
+#~ msgid "You died."
+#~ msgstr "Vous êtes mort."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index fb95014bbe0cff772805a648b475b39e2b09513c..dcc811dd4a95131e6ade8127d25f1d8690e4339b 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2020-06-22 17:56+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-08-19 06:36+0000\n"
 "Last-Translator: GunChleoc <fios@foramnagaidhlig.net>\n"
 "Language-Team: Gaelic <https://hosted.weblate.org/projects/minetest/minetest/"
 "gd/>\n"
@@ -18,7 +18,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : "
 "(n > 2 && n < 20) ? 2 : 3;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
@@ -65,10 +65,6 @@ msgstr ""
 msgid "You died"
 msgstr ""
 
-#: builtin/client/death_formspec.lua
-msgid "You died."
-msgstr ""
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -98,6 +94,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr ""
@@ -299,6 +299,12 @@ msgstr ""
 msgid "Install missing dependencies"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"Stàladh: Faidhle dhen t-seòrsa “$1” ris nach eil taic no tasglann bhriste"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -624,7 +630,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -734,15 +740,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Stàladh: Faidhle dhen t-seòrsa “$1” ris nach eil taic no tasglann bhriste"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1109,12 +1106,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-"Airson sgàileadairean a chur an comas, feumaidh tu draibhear OpenGL a "
-"chleachdadh."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1147,7 +1138,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1176,7 +1167,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1220,15 +1211,6 @@ msgstr ""
 msgid "- Address: "
 msgstr " "
 
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Creative Mode: "
-msgstr " "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "– Dochann: "
-
 #: src/client/game.cpp
 #, fuzzy
 msgid "- Mode: "
@@ -1255,6 +1237,15 @@ msgstr " "
 msgid "- Server Name: "
 msgstr " "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1263,6 +1254,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1271,6 +1278,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1283,6 +1294,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr "Tha am modh film an comas"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1291,6 +1306,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1328,6 +1347,11 @@ msgstr ""
 "- Cuibhle na luchaige: tagh nì\n"
 "- %s: cabadaich\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1520,6 +1544,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1854,6 +1893,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2049,8 +2096,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-#, fuzzy
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr " "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2162,10 +2209,10 @@ msgid ""
 "a value range of approximately -2.0 to 2.0."
 msgstr ""
 "Riasladh 3D a mhìnicheas structar na tìre air fhleòd.\n"
-"Mura cleachd thu an luach tùsail, dh’fhaoidte gum fheàirrde thu gleus a chur "
-"air “scale” an riaslaidh (0.7 o thùs)\n"
-", on a dh’obraicheas foincseanan cinn-chaoil as fheàrr\n"
-"nuair a bhios an riasladh seo eadar mu -2.0 agus 2.0."
+"Mura cleachd thu an luach bunaiteach, dh’fhaoidte gum b’ fheàirrde thu\n"
+"gleus a chur air “scale” an riaslaidh (0.7 a ghnàth) on a dh’obraicheas "
+"foincseanan\n"
+"cinn-chaoil as fheàrr nuair a bhios an riasladh seo eadar mu -2.0 agus 2.0."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining structure of river canyon walls."
@@ -2265,6 +2312,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2538,6 +2589,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Tha a’ chabadaich ’ga shealltainn"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2571,8 +2627,9 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Tha a’ chabadaich ’ga shealltainn"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2590,6 +2647,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2665,6 +2728,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2756,7 +2835,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2821,7 +2900,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Default privileges"
-msgstr "Sochairean tùsail"
+msgstr "Sochairean bunaiteach"
 
 #: src/settings_translation_file.cpp
 msgid "Default report format"
@@ -2833,8 +2912,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2954,6 +3033,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3000,7 +3083,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3028,13 +3118,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3119,6 +3202,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3314,11 +3403,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3327,6 +3420,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3386,10 +3490,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3437,10 +3537,11 @@ msgid "Global callbacks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Buadhan gintinn mapa uile-choitcheann.\n"
 "Ann an gineadair nam mapa v6, stiùirichidh bratach “decorations” sgeadachadh "
@@ -3898,7 +3999,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3987,7 +4088,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4979,7 +5080,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5280,7 +5381,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5291,6 +5392,10 @@ msgstr "Slighe dhan chlò aon-leud"
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5417,7 +5522,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5443,11 +5548,13 @@ msgstr ""
 "Fosgail clàr-taice a’ chuir ’na stad nuair a chailleas an uinneag am fòcas.\n"
 "Cha dèid a chur ’na stad nuair a bhios formspec fosgailte."
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5470,17 +5577,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5586,9 +5689,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5883,26 +5986,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5993,7 +6088,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6105,6 +6200,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6230,7 +6333,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6248,7 +6351,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6320,7 +6423,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6413,6 +6516,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6487,7 +6594,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6672,6 +6779,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6693,7 +6804,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6701,14 +6812,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6845,24 +6949,6 @@ msgstr "Àirde-Y a’ chrutha-thìre ìosal agus grunnd na mara."
 msgid "Y-level of seabed."
 msgstr "Àirde-Y aig grunnd na mara."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6875,6 +6961,13 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#, fuzzy
+#~ msgid "- Creative Mode: "
+#~ msgstr " "
+
+#~ msgid "- Damage: "
+#~ msgstr "– Dochann: "
+
 #~ msgid "Address / Port"
 #~ msgstr "Seòladh / Port"
 
@@ -6883,5 +6976,10 @@ msgstr ""
 #~ "Claonadh na h-èifeachd occlusion na paraileig air fheadh, seo sgèile/2 "
 #~ "mar as àbhaist."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr ""
+#~ "Airson sgàileadairean a chur an comas, feumaidh tu draibhear OpenGL a "
+#~ "chleachdadh."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index a9afc1ac6ceebfe83d3db9db084ecdcf52496fa4..1593600ff492efba0d1c6ee2115b093d0c73e3cf 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2020-07-08 20:47+0000\n"
 "Last-Translator: sfan5 <sfan5@live.de>\n"
 "Language-Team: Galician <https://hosted.weblate.org/projects/minetest/"
@@ -64,11 +64,6 @@ msgstr "Reaparecer"
 msgid "You died"
 msgstr "Morreches"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Morreches"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -98,6 +93,10 @@ msgstr ""
 msgid "OK"
 msgstr "Vale"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr ""
@@ -296,6 +295,10 @@ msgstr ""
 msgid "Install missing dependencies"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -621,7 +624,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -731,14 +734,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1102,10 +1097,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1138,7 +1129,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1167,7 +1158,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1208,14 +1199,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1237,6 +1220,15 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1245,6 +1237,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1253,6 +1261,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1265,6 +1277,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1273,6 +1289,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1296,6 +1316,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1488,6 +1513,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1822,6 +1862,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2017,7 +2065,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2224,6 +2273,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2490,6 +2543,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2523,7 +2580,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2542,6 +2599,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2617,6 +2680,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2708,7 +2787,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2785,8 +2864,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2904,6 +2983,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2950,7 +3033,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2978,13 +3068,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3069,6 +3152,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3253,11 +3342,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3266,6 +3359,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3325,10 +3429,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3377,7 +3477,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3809,7 +3909,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3893,7 +3993,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4722,7 +4822,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5015,7 +5115,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5026,6 +5126,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5147,7 +5251,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5171,11 +5275,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5198,17 +5304,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5311,9 +5413,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5606,26 +5708,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5716,7 +5810,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5821,6 +5915,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5931,7 +6033,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5949,7 +6051,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6018,7 +6120,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6111,6 +6213,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6181,7 +6287,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6364,6 +6470,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6385,7 +6495,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6393,14 +6503,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6526,24 +6629,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6556,5 +6641,9 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Morreches"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 8bc1c5fefe2536fcfd8ac4aa3c5d40ca90b17d2f..a6beb9def46f345cad25d0e44938241e8ecf7254 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Hebrew (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-04-17 07:27+0000\n"
 "Last-Translator: Omer I.S. <omeritzicschwartz@gmail.com>\n"
 "Language-Team: Hebrew <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -64,11 +64,6 @@ msgstr "הזדמן"
 msgid "You died"
 msgstr "מתת"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "מתת"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -100,6 +95,10 @@ msgstr ""
 msgid "OK"
 msgstr "אישור"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "אירעה שגיאה בתסריט Lua:"
@@ -302,6 +301,11 @@ msgstr "התקנת $1"
 msgid "Install missing dependencies"
 msgstr "מתקין תלויות חסרות"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "התקנה: סוג קובץ לא נתמך \"$1\" או שהארכיב פגום"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -629,7 +633,8 @@ msgid "Offset"
 msgstr "היסט"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "התמדה"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -739,14 +744,6 @@ msgstr "התקנת שיפור: לא ניתן למצוא את שם השיפור 
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "התקנת שיפור: לא ניתן למצוא שם תיקייה מתאים לערכת השיפורים $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "התקנה: סוג קובץ לא נתמך \"$1\" או שהארכיב פגום"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "התקנה: מקובץ: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "אין אפשרות למצוא שיפור או ערכת שיפורים במצב תקין"
@@ -1119,10 +1116,6 @@ msgstr "החלקת תאורה"
 msgid "Texturing:"
 msgstr "טקסטורות:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "כדי לאפשר שיידרים יש להשתמש בדרייבר של OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "מיפוי גוונים"
@@ -1155,7 +1148,7 @@ msgstr "נוזלים עם גלים"
 msgid "Waving Plants"
 msgstr "צמחים מתנוענעים"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "זמן המתנה לחיבור אזל."
 
@@ -1184,7 +1177,8 @@ msgid "Connection error (timed out?)"
 msgstr "בעיה בחיבור (נגמר זמן ההמתנה?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "לא מצליח למצוא או לטעון משחק \""
 
 #: src/client/clientlauncher.cpp
@@ -1227,14 +1221,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- כתובת: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- מצב יצירתי: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- חבלה: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- מצב: "
@@ -1256,6 +1242,16 @@ msgstr "- קרב: "
 msgid "- Server Name: "
 msgstr "- שם שרת: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "אירעה שגיאה:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "התקדמות אוטומטית קדימה מבוטלת"
@@ -1264,6 +1260,22 @@ msgstr "התקדמות אוטומטית קדימה מבוטלת"
 msgid "Automatic forward enabled"
 msgstr "תנועה קדימה אוטומטית מופעל"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "עדכון מצלמה מבוטל"
@@ -1272,6 +1284,10 @@ msgstr "עדכון מצלמה מבוטל"
 msgid "Camera update enabled"
 msgstr "עדכון מצלמה מופעל"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "שנה סיסמה"
@@ -1284,6 +1300,11 @@ msgstr "מצב קולנועי מבוטל"
 msgid "Cinematic mode enabled"
 msgstr "מצב קולנועי מופעל"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "קלינט"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "סקריפטים בצד לקוח מבוטלים"
@@ -1292,6 +1313,10 @@ msgstr "סקריפטים בצד לקוח מבוטלים"
 msgid "Connecting to server..."
 msgstr "מתחבר לשרת..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "המשך"
@@ -1329,6 +1354,11 @@ msgstr ""
 "- גלגלת העכבר: כדי לבחור פריט\n"
 "- %s: כדי לפתוח את הצ׳אט\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "יוצר לקוח..."
@@ -1534,6 +1564,21 @@ msgstr "מערכת שמע לא נתמכת בבניה הנוכחית"
 msgid "Sound unmuted"
 msgstr "מערכת שמע מופעלת"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1868,6 +1913,15 @@ msgstr "מפה קטנה במצב שטח, זום x %d"
 msgid "Minimap in texture mode"
 msgstr "מפה קטנה במצב טקסטורה"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "הורדת $1 נכשלה"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "סיסמאות לא תואמות!"
@@ -2068,7 +2122,8 @@ msgid "Muted"
 msgstr "מושתק"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "עוצמת שמע: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2318,6 +2373,10 @@ msgid ""
 "screens."
 msgstr "התאם את תצורת dpi למסך שלך (לא X11 / Android בלבד) למשל. למסכי 4k."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2612,6 +2671,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "סף בעיטה להודעות צ'אט"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "פקודות צ'אט"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "גודל גופן צ'אט"
@@ -2645,8 +2709,9 @@ msgid "Chat toggle key"
 msgstr "מתג הפעלת צ'אט"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "פקודות צ'אט"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "צ'אט מוצג"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2664,6 +2729,12 @@ msgstr "מקש מצב קולנועי"
 msgid "Clean transparent textures"
 msgstr "טקסטורות נקיות ושקופות"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "לקוח"
@@ -2741,6 +2812,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2832,7 +2919,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2909,8 +2996,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3030,6 +3117,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3076,7 +3167,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3104,13 +3202,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr "לאפשר חבלה ומוות של השחקנים."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3195,6 +3286,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3379,11 +3476,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3392,6 +3493,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3451,10 +3563,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3503,7 +3611,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3937,7 +4045,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4021,7 +4129,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4850,7 +4958,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5149,7 +5257,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5160,6 +5268,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5281,7 +5393,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5305,11 +5417,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5332,17 +5446,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5446,9 +5556,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5741,26 +5851,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5854,7 +5956,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5959,6 +6061,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6069,7 +6179,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6087,7 +6197,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6156,7 +6266,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6249,6 +6359,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6319,7 +6433,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6505,6 +6619,10 @@ msgstr "אורך גל של נוזלים עם גלים"
 msgid "Waving plants"
 msgstr "צמחים מתנופפים"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6526,7 +6644,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6534,14 +6652,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6669,24 +6780,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "(cURL) זמן להורדה נגמר"
@@ -6700,6 +6793,12 @@ msgstr "(cURL) מגבלת זמן"
 msgid "cURL parallel limit"
 msgstr "(cURL) מגבלה לפעולות במקביל"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- מצב יצירתי: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- חבלה: "
+
 #~ msgid "Address / Port"
 #~ msgstr "כתובת / פורט"
 
@@ -6719,6 +6818,9 @@ msgstr "(cURL) מגבלה לפעולות במקביל"
 #~ msgid "Enable VBO"
 #~ msgstr "אפשר בכל"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "התקנה: מקובץ: \"$1\""
+
 #~ msgid "Main menu style"
 #~ msgstr "סגנון התפריט הראשי"
 
@@ -6741,11 +6843,18 @@ msgstr "(cURL) מגבלה לפעולות במקביל"
 #~ msgid "Special"
 #~ msgstr "מיוחד"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "כדי לאפשר שיידרים יש להשתמש בדרייבר של OpenGL."
+
 #~ msgid "View"
 #~ msgstr "תצוגה"
 
 #~ msgid "Yes"
 #~ msgstr "כן"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "מתת"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index 59326cf068ee7f879b8c1a2b87b9ff07c89a7de9..f21076beb182cc9c891bd5a4e236a102fd886256 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2020-10-06 14:26+0000\n"
 "Last-Translator: Eyekay49 <satvikpatwardhan@gmail.com>\n"
 "Language-Team: Hindi <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -67,11 +67,6 @@ msgstr "वापस ज़िंदा होएं"
 msgid "You died"
 msgstr "आपकी मौत हो गयी"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "आपकी मौत हो गयी"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -103,6 +98,10 @@ msgstr ""
 msgid "OK"
 msgstr "ठीक है"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua कोड में यह परेशानी हुई :"
@@ -308,6 +307,11 @@ msgstr "इन्स्टाल करें"
 msgid "Install missing dependencies"
 msgstr "अनावश्यक निर्भरताएं :"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "इन्स्टाल : \"$1\" का फाईल टाईप अंजान है याफिर आरकाइव खराब है"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -635,7 +639,8 @@ msgid "Offset"
 msgstr "आफसेट"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "हठ (पर्सिस्टेन्स)"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -745,14 +750,6 @@ msgstr "इन्स्टाल मॉड: $1 का असल नाम नह
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "माॅड इन्स्टाल: माॅडपैक $1 के लिए सही फोल्डर नहीं ढूंढा जा सका"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "इन्स्टाल : \"$1\" का फाईल टाईप अंजान है याफिर आरकाइव खराब है"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "इन्स्टाल : फाईल : \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "सही माॅड या माॅडपैक नहीं ढूंढ पाया गया"
@@ -1126,10 +1123,6 @@ msgstr "चिकना उजाला"
 msgid "Texturing:"
 msgstr "कला बनावट :"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "छाया बनावट कॆ लिये OpenGL ड्राईवर आवश्यक हैं|"
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "टोन मैपिंग"
@@ -1162,7 +1155,7 @@ msgstr "पानी में लहरें बनें"
 msgid "Waving Plants"
 msgstr "पाैधे लहराएं"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "कनेक्शन समय अंत|"
 
@@ -1191,7 +1184,8 @@ msgid "Connection error (timed out?)"
 msgstr "कनेक्शन खराबी (समय अंत?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "खेल ढूंढा ना जा सका या लोड नहीं किया जा सका \""
 
 #: src/client/clientlauncher.cpp
@@ -1234,14 +1228,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- एड्रेस : "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- असीमित साधन "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- हानि : "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- तकनीक : "
@@ -1263,6 +1249,16 @@ msgstr "- खिलाड़ियों में मारा-पीटी : "
 msgid "- Server Name: "
 msgstr "- सर्वर का नाम : "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "एक खराबी हो गयी :"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "स्वचाल रुका हुआ"
@@ -1271,6 +1267,22 @@ msgstr "स्वचाल रुका हुआ"
 msgid "Automatic forward enabled"
 msgstr "स्वचाल चालू"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "कैमरा रुका हुआ"
@@ -1279,6 +1291,10 @@ msgstr "कैमरा रुका हुआ"
 msgid "Camera update enabled"
 msgstr "कैमरा चालू"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "पासवर्ड बदलें"
@@ -1291,6 +1307,10 @@ msgstr "सिनेमा चाल रुका हुआ"
 msgid "Cinematic mode enabled"
 msgstr "सिनेमा चाल चालू"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "क्लाइंट की तरफ से स्क्रिप्ट लगाना मना है"
@@ -1299,6 +1319,10 @@ msgstr "क्लाइंट की तरफ से स्क्रिप्
 msgid "Connecting to server..."
 msgstr "सर्वर से कनेक्ट हुआ जा रहा है ..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "आगे बढ़ें"
@@ -1336,6 +1360,11 @@ msgstr ""
 "- : माउस पहिया : वस्तु चुनें\n"
 "- %s : बात करने के लिए\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "क्लाइंट बनाया जा रहा है ..."
@@ -1541,6 +1570,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "आवाज चालू"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1876,6 +1920,15 @@ msgstr "छोटा नक्शा जमीन मोड, 1 गुना ज
 msgid "Minimap in texture mode"
 msgstr "छोटा नक्शा जमीन मोड, 1 गुना ज़ूम"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "$1 का डाऊनलोड असफल हुआ"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "पासवर्ड अलग-अलग हैं!"
@@ -2077,7 +2130,8 @@ msgid "Muted"
 msgstr "चुप"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "आवाज "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2284,6 +2338,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2551,6 +2609,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "आज्ञा"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2584,8 +2647,9 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "बातें दिखाई देंगी"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2603,6 +2667,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2678,6 +2748,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2769,7 +2855,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2846,8 +2932,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2965,6 +3051,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3011,7 +3101,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3039,13 +3136,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3130,6 +3220,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3317,11 +3413,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3330,6 +3430,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3389,10 +3500,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3441,7 +3548,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3883,7 +3990,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3967,7 +4074,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4796,7 +4903,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5089,7 +5196,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5100,6 +5207,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5221,7 +5332,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5245,11 +5356,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5272,17 +5385,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5388,9 +5497,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5683,26 +5792,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5793,7 +5894,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5900,6 +6001,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6010,7 +6119,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6028,7 +6137,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6097,7 +6206,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6190,6 +6299,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6260,7 +6373,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6443,6 +6556,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6464,7 +6581,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6472,14 +6589,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6605,24 +6715,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6635,6 +6727,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- असीमित साधन "
+
+#~ msgid "- Damage: "
+#~ msgstr "- हानि : "
+
 #~ msgid "Address / Port"
 #~ msgstr "ऐडरेस / पोर्ट"
 
@@ -6665,6 +6763,9 @@ msgstr ""
 #~ msgid "Generate Normal Maps"
 #~ msgstr "मामूली नक्शे बनाएं"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "इन्स्टाल : फाईल : \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "मुख्य"
 
@@ -6707,11 +6808,18 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "एक-खिलाडी शुरू करें"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "छाया बनावट कॆ लिये OpenGL ड्राईवर आवश्यक हैं|"
+
 #~ msgid "View"
 #~ msgstr "दृश्य"
 
 #~ msgid "Yes"
 #~ msgstr "हां"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "आपकी मौत हो गयी"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index dae8e92b70844037b05126948fde21957aeb210a..ab9d0c49fb18f528179119498c883fad4b71e1aa 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Hungarian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-03-28 20:29+0000\n"
-"Last-Translator: Hatlábú Farkas <hatlabufarkas@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-29 21:28+0000\n"
+"Last-Translator: Balázs Kovács <kovacs.balazs.ktk@gmail.com>\n"
 "Language-Team: Hungarian <https://hosted.weblate.org/projects/minetest/"
 "minetest/hu/>\n"
 "Language: hu\n"
@@ -12,48 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.6-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Kimenő üzenetek sorának törlése"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Parancsok"
+msgstr "Üres parancs."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
 msgstr "Kilépés a főmenübe"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Helyi parancs"
+msgstr "Érvénytelen parancs: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Kiadott parancs: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Egyjátékos"
+msgstr "Online játékosok listázása"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Egyjátékos"
+msgstr "Online játékosok: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "A kiemenő üzenetek sora jelenleg üres."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Ezt a parancsot a szerver letiltotta."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -63,42 +58,41 @@ msgstr "Újraéledés"
 msgid "You died"
 msgstr "Meghaltál"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Meghaltál"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Helyi parancs"
+msgstr "Elérhető parancsok:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Helyi parancs"
+msgstr "Elérhető parancsok: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "A parancs nem elérhető: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Segítség kérése a parancsokhoz"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"További információkhoz adja ki a '.help <cmd>' parancsot, vagy az összes "
+"kilistázásához a '.help all' parancsot."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OKÉ"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<egy sem elérhető>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Hiba történt egy Lua parancsfájlban:"
@@ -189,7 +183,7 @@ msgstr "Mod:"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No (optional) dependencies"
-msgstr "Nincsenek (választható) függőségek:"
+msgstr "Nincsenek (választható) függőségek"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No game description provided."
@@ -197,7 +191,7 @@ msgstr "Nincs elérhető játékleírás."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No hard dependencies"
-msgstr "Nincsenek függőségek."
+msgstr "Nincsenek kötelező függőségek"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No modpack description provided."
@@ -205,7 +199,7 @@ msgstr "Nincs elérhető modcsomag-leírás."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No optional dependencies"
-msgstr "Nincsenek választható függőségek"
+msgstr "Nincsenek választható függőségek"
 
 #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua
 msgid "Optional dependencies:"
@@ -230,11 +224,11 @@ msgstr "\"$1\" már létezik. Szeretné felülírni?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
-msgstr ""
+msgstr "$1 és $2 függőségek telepítve lesznek."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1 az $2-ből"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
@@ -250,11 +244,11 @@ msgstr "$1 Letöltése…"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr ""
+msgstr "Ehhez szükséges függőségek nem találhatók: $1."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
-msgstr ""
+msgstr "$1 telepítve lesz, és $2 függőségek ki lesznek hagyva."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "All packages"
@@ -301,6 +295,10 @@ msgstr "$1 telepítése"
 msgid "Install missing dependencies"
 msgstr "hiányzó függőségek telepitése"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Telepítés: nem támogatott fájltípus vagy sérült archívum"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -412,11 +410,11 @@ msgstr "Lapos terep"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floating landmasses in the sky"
-msgstr "Lebegő földdarabok az égben"
+msgstr "Lebegő földtömegek az égben"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floatlands (experimental)"
-msgstr "Lebegő földek"
+msgstr "Lebegő földek (kísérleti)"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Game"
@@ -632,7 +630,7 @@ msgid "Offset"
 msgstr "Eltolás"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Folytonosság"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -743,14 +741,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Mod telepítése: nem található megfelelő mappanév ehhez a modcsomaghoz: $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Telepítés: nem támogatott „$1” fájltípus, vagy sérült archívum"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Fájl telepítése: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Nem található érvényes mod vagy modcsomag"
@@ -787,16 +777,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Névjegy"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Aktív közreműködők"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Aktív objektum küldés hatótávolsága"
+msgstr "Aktív renderelő:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -932,9 +921,8 @@ msgid "Start Game"
 msgstr "Indítás"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Cím: "
+msgstr "Cím"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -950,22 +938,20 @@ msgstr "Kreatív mód"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Sérülés"
+msgstr "Sérülés / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Kedvenc törlése"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Kedvenc"
+msgstr "Kedvencek"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Inkompatibilis szerverek"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -976,18 +962,16 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Szerver nyilvánossá tétele"
+msgstr "Nyilvános szerverek"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Frissítés"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Szerver leírása"
+msgstr "Szerver leírás"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1030,13 +1014,12 @@ msgid "Connected Glass"
 msgstr "Csatlakozó üveg"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Betűtípus árnyéka"
+msgstr "Dinamikus árnyékok"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dinamikus árnyékok: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1044,15 +1027,15 @@ msgstr "Szép levelek"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Magas"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Alacsony"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Közepes"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1126,10 +1109,6 @@ msgstr "Simított megvilágítás"
 msgid "Texturing:"
 msgstr "Textúrázás:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Az árnyalók engedélyezéséhez OpenGL driver használata szükséges."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tónus rajzolás"
@@ -1144,11 +1123,11 @@ msgstr "Trilineáris szűrés"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Nagyon magas"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Nagyon alacsony"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1162,7 +1141,7 @@ msgstr "Hullámzó folyadékok"
 msgid "Waving Plants"
 msgstr "Hullámzó növények"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Csatlakozási idő lejárt."
 
@@ -1191,8 +1170,8 @@ msgid "Connection error (timed out?)"
 msgstr "Kapcsolódási hiba (időtúllépés?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Nem található vagy nem betölthető a játék"
+msgid "Could not find or load game"
+msgstr "Nem található vagy nem betölthető a játék"
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1234,14 +1213,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Cím: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kreatív mód: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Sérülés: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Mód: "
@@ -1263,6 +1234,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Kiszolgáló neve: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Szerializációs hiba történt:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Hozzáférés megtagadva. Oka: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automatikus előre kikapcsolva"
@@ -1271,6 +1251,22 @@ msgstr "Automatikus előre kikapcsolva"
 msgid "Automatic forward enabled"
 msgstr "Automatikus előre engedélyezve"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Blokkhatárok elrejtve"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Blokkhatárok mutatása minden blokk esetén"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Blokkhatárok mutatása az aktuális blokk esetén"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Blokkhatárok mutatása a közeli blokkok esetén"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kamera frissítés letiltva"
@@ -1279,9 +1275,14 @@ msgstr "Kamera frissítés letiltva"
 msgid "Camera update enabled"
 msgstr "Kamera frissítés engedélyezve"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+"Blokkhatárok mutatása nem lehetséges ('basic_debug' jogosultság szükséges)"
+
 #: src/client/game.cpp
 msgid "Change Password"
-msgstr "Jelszó változtatása"
+msgstr "Jelszó Módosítása"
 
 #: src/client/game.cpp
 msgid "Cinematic mode disabled"
@@ -1291,6 +1292,10 @@ msgstr "Filmszerű mód letiltva"
 msgid "Cinematic mode enabled"
 msgstr "Filmszerű mód engedélyezve"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Kliens lecsatlakozott"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Kliens oldali szkriptek letiltva"
@@ -1299,12 +1304,16 @@ msgstr "Kliens oldali szkriptek letiltva"
 msgid "Connecting to server..."
 msgstr "Kapcsolódás szerverhez..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Kapcsolat megszakadt ismeretlen okból"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Folytatás"
 
 #: src/client/game.cpp
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "Controls:\n"
 "- %s: move forwards\n"
@@ -1327,15 +1336,20 @@ msgstr ""
 "- %s: mozgás balra\n"
 "- %s: mozgás jobbra\n"
 "- %s: ugrás/mászás\n"
+"- %s: ásás/ütés\n"
+"- %s: letevés/használat\n"
 "- %s: lopakodás/lefelé mászás\n"
 "- %s: tárgy eldobása\n"
-"- %s: eszköztár\n"
+"- %s: felszerelés\n"
 "- Egér: forgás/nézelődés\n"
-"- Bal-egér: ásás/ütés\n"
-"- Jobb-egér: elhelyezés/használat\n"
-"- Egér görgő: tárgy választása\n"
+"- Egérgörgő: tárgy kiválasztása\n"
 "- %s: csevegés\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Cím feloldása sikertelen: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Kliens létrehozása…"
@@ -1372,17 +1386,17 @@ msgid ""
 " --> place single item to slot\n"
 msgstr ""
 "Alapértelmezett irányítás:\n"
-"Nem látható menü:\n"
+"Ha nem látható menü:\n"
 "- egy érintés: gomb aktiválás\n"
 "- dupla érintés: lehelyezés/használat\n"
 "- ujj csúsztatás: körbenézés\n"
-"Menü/Eszköztár látható:\n"
+"Ha a Menü/Felszerelés látható:\n"
 "- dupla érintés (kívül):\n"
 " -->bezárás\n"
-"- stack, vagy slot érintése:\n"
-" --> stack mozgatás\n"
+"- köteg, vagy hely érintése:\n"
+" --> köteg mozgatás\n"
 "- \"érint&húz\", érintés 2. ujjal\n"
-" --> egy elem slotba helyezése\n"
+" --> letesz egyetlen tárgyat a helyre\n"
 
 #: src/client/game.cpp
 msgid "Disabled unlimited viewing range"
@@ -1465,9 +1479,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "A kistérkép letiltva (szerver, vagy mod által)"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Egyjátékos"
+msgstr "Többjátékos"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1541,6 +1554,21 @@ msgstr "A hangrendszer nem támogatott ebben build-ben"
 msgid "Sound unmuted"
 msgstr "Hang visszahangosítva"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "A szerveren valószínűleg a %s másik verziója fut."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Nem lehet csatlakozni a %s-hoz mivel az IPv6 nincs engedélyezve"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Nem lehet figyelni a %s-t mert az IPv6 nincs engedélyezve"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1596,7 +1624,7 @@ msgstr "Profiler elrejtése"
 #: src/client/gameui.cpp
 #, c-format
 msgid "Profiler shown (page %d of %d)"
-msgstr "Profiler megjelenítése (lap: %d1 ennyiből :  %d2)"
+msgstr "Profiler megjelenítése (lap: %d1 ennyiből: %d2)"
 
 #: src/client/keycode.cpp
 msgid "Apps"
@@ -1869,12 +1897,20 @@ msgstr "Minimap radar módban, Nagyítás x%d"
 #: src/client/minimap.cpp
 #, c-format
 msgid "Minimap in surface mode, Zoom x%d"
-msgstr "kistérkép terület módban  x%d"
+msgstr "kistérkép terület módban x%d"
 
 #: src/client/minimap.cpp
 msgid "Minimap in texture mode"
 msgstr "Minimap textúra módban"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Weblap megnyitása nem sikerült"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Weblap megnyitása"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "A jelszavak nem egyeznek!"
@@ -1892,21 +1928,20 @@ msgid ""
 "Please retype your password and click 'Register and Join' to confirm account "
 "creation, or click 'Cancel' to abort."
 msgstr ""
-"Te most %1$s szerverre csatlakozol \"%2$s\" névvel először.\n"
-"Ha folytatod, akkor egy új fiók lesz létrehozva a hitelesítő adatokkal a "
+"Most először csatlakozol erre a szerverre a \"%s\" névvel.\n"
+"Ha folytatod, akkor a hitelesítő adataiddal egy új fiók jön létre a "
 "szerveren.\n"
-"Kérlek írd be újra a jelszavad, kattints Regisztrációra majd "
-"Bejelentkezésre, hogy megerősítsd a fióklétrehozást vagy kattints Kilépés "
-"gombra a megszakításhoz."
+"Kérlek írd be újra a jelszavad, majd kattints a \"Regisztráció és "
+"Bejelentkezés\"-re, hogy megerősítsd a fióklétrehozást, vagy kattints a "
+"\"Mégse\" gombra a megszakításhoz."
 
 #: src/gui/guiFormSpecMenu.cpp
 msgid "Proceed"
 msgstr "Folytatás"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "különleges = lemászás"
+msgstr "\"Aux1\" = lemászás"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1918,7 +1953,7 @@ msgstr "Automatikus ugrás"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1926,7 +1961,7 @@ msgstr "Hátra"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Blokkhatárok"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2079,8 +2114,9 @@ msgid "Muted"
 msgstr "Némitva"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Hangerő: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Hangerő: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2105,14 +2141,13 @@ msgstr ""
 "kattintás' pozícióban."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Használd a virtuális joystick-ot az \"aux\" gomb kapcsolásához.\n"
-"Ha ez engedélyezve van, akkor a virtuális joystick is aktiválja az aux "
+"(Android) Használd a virtuális joystick-ot az \"Aux1\" gomb kapcsolásához.\n"
+"Ha ez engedélyezve van, akkor a virtuális joystick is aktiválja az \"Aux1\" "
 "gombot ha kint van a fő körből."
 
 #: src/settings_translation_file.cpp
@@ -2126,6 +2161,17 @@ msgid ""
 "situations.\n"
 "Range roughly -2 to 2. Multiply by 'scale' for offset in nodes."
 msgstr ""
+"A fraktál (X,Y,Z) relatív pozíciója a világ közepéhez képest, egységekben "
+"mérve.\n"
+"Használható arra, hogy egy kívánt pontot a (0, 0)-ra tegyünk, hogy "
+"megfelelő\n"
+"játékoskezdőpontot készítsünk, vagy hogy \"rázoomoljunk\" egy kívánt pontra\n"
+"az egység növelése által.\n"
+"Az alapérték úgy lett meghatározva, hogy megfelelő játékoskezdőpontot adjon\n"
+"az alapparaméterekkel generált Mandelbrot-halmazokhoz, de egyéb esetben\n"
+"lehet, hogy meg kell változtatni.\n"
+"Nagyjából -2 és 2 közötti értékek. Blokkokban mért pozícióhoz szorzzunk az "
+"egységgel."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2137,6 +2183,13 @@ msgid ""
 "Default is for a vertically-squashed shape suitable for\n"
 "an island, set all 3 numbers equal for the raw shape."
 msgstr ""
+"A fraktál (X,Y,Z) méretezési faktora blokktávolságban kifejezve.\n"
+"A fraktál tényleges mérete 2-3-szorosa lesz ennek.\n"
+"Ezek a számok nagyon nagyok is lehetnek, a fraktálnak\n"
+"nem kell elférnie a világban.\n"
+"Növelje meg, hogy \"rázoomoljon\" a fraktál részleteire.\n"
+"Az alapérték egy függőlegesen összenyomott alakot ad, amely\n"
+"szigetekhez alkalmas. Ha a 3 szám egyenlő, a nyers alakot kapjuk."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of ridged mountains."
@@ -2161,7 +2214,7 @@ msgstr "2D zaj, amely a dombok méretét/előfordulását szabályozza."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of step mountain ranges."
-msgstr ""
+msgstr "2D zaj, amely a lépcsős hegységek méretét/előrordulását szabályozza."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that locates the river valleys and channels."
@@ -2178,7 +2231,7 @@ msgstr "3D mód"
 
 #: src/settings_translation_file.cpp
 msgid "3D mode parallax strength"
-msgstr ""
+msgstr "3D mód parallax hatásának erőssége"
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining giant caverns."
@@ -2190,7 +2243,7 @@ msgid ""
 "Also defines structure of floatland mountain terrain."
 msgstr ""
 "A hegyek szerkezetét és magasságát meghatározó 3D zaj.\n"
-"A lebegő tájak hegyeit is meghatározza."
+"A lebegő földek hegyeit is meghatározza."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2199,6 +2252,10 @@ msgid ""
 "to be adjusted, as floatland tapering functions best when this noise has\n"
 "a value range of approximately -2.0 to 2.0."
 msgstr ""
+"A lebegő földek szerkezetét meghatározó 3D zaj.\n"
+"Ha az alapértékekekt megváltoztatják, a zajszintet is át kell állítani\n"
+"(0,7 alapbeállításban), mivel a lebegő földeket vékonyítása akkor a\n"
+"leghatékonyabb, ha ez az érték körülbelül -2,0 és 2,0 közötti."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining structure of river canyon walls."
@@ -2218,7 +2275,6 @@ msgid "3D noise that determines number of dungeons per mapchunk."
 msgstr "3D-s zaj, amely meghatározza a tömlöcök számát egy térképdarabkánként."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "3D support.\n"
 "Currently supported:\n"
@@ -2233,12 +2289,14 @@ msgid ""
 msgstr ""
 "3D támogatás.\n"
 "Jelenleg támogatott:\n"
-"- none: nincs 3d kimenet.\n"
-"- anaglyph: cián/magenta színű 3d.\n"
-"- interlaced: odd/even line based polarisation screen support.\n"
-"- topbottom: osztott képernyő fent/lent.\n"
-"- sidebyside: osztott képernyő kétoldalt.\n"
-"- pageflip: quadbuffer based 3d."
+"-    none: nincs 3d kimenet.\n"
+"-    anaglyph: cián/magenta színű 3d.\n"
+"-    interlaced: páros/páratlan soralapú polarizációs képernyő támogatás.\n"
+"-    topbottom: osztott képernyő fent/lent.\n"
+"-    sidebyside: osztott képernyő kétoldalt.\n"
+"-    crossview: bandzsítva nézendő 3d\n"
+"-    pageflip: quadbuffer alapú 3d.\n"
+"Ne feledje, hogy az interlaced üzemmód, igényli az árnyékolók használatát."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2258,15 +2316,15 @@ msgstr "Az összes kliensen megjelenített üzenet a szerver leállításakor."
 
 #: src/settings_translation_file.cpp
 msgid "ABM interval"
-msgstr ""
+msgstr "ABM intervallum"
 
 #: src/settings_translation_file.cpp
 msgid "ABM time budget"
-msgstr ""
+msgstr "ABM időgazdálkodás"
 
 #: src/settings_translation_file.cpp
 msgid "Absolute limit of queued blocks to emerge"
-msgstr ""
+msgstr "A várakozó blokkok felbukkanásának határa"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration in air"
@@ -2314,6 +2372,12 @@ msgstr ""
 "Dpi konfiguráció igazítása a képernyődhöz (nem X11/csak Android) pl. 4k "
 "képernyőkhöz."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Az észlelt képsűrűség kiigazítása a felhasználói felület elemeinek "
+"méretezéséhez."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2323,6 +2387,13 @@ msgid ""
 "Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n"
 "to be sure) creates a solid floatland layer."
 msgstr ""
+"A lebegő föld réteg sűrűségét szabályozza.\n"
+"Nagyobb sűrűséghez használjon nagyobb értéket. Lehet pozitív vagy negatív is."
+"\n"
+"Érték = 0,0: a térfogat 50%-a lebegő föld.\n"
+"Érték = 2,0 (magasabb is lehet az 'mgv7_np_floatland'-től függően, a "
+"biztonság\n"
+"kedvéért mindig próbálja ki) egybefüggő lebegő föld réteget eredményez."
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
@@ -2336,6 +2407,11 @@ msgid ""
 "This only has significant effect on daylight and artificial\n"
 "light, it has very little effect on natural night light."
 msgstr ""
+"Módosítja a fénygörbét gamma korrekció hozzáadásával.\n"
+"Magasabb értékek esetén a közepes és alacsony fényszintek világosabbak.\n"
+"Az 1,0-ás érték a fénygörbét érintetlenül hagyja.\n"
+"Csak a nappali és a mesterséges fényt befolyásolja jelentősen,\n"
+"a természetes éjszakai fényre nagyon kis hatása van."
 
 #: src/settings_translation_file.cpp
 msgid "Always fly and fast"
@@ -2343,7 +2419,7 @@ msgstr "Repülés és gyors mód mindig"
 
 #: src/settings_translation_file.cpp
 msgid "Ambient occlusion gamma"
-msgstr "Ambiens okklúzió gamma"
+msgstr "Környezeti árnyékolás gamma"
 
 #: src/settings_translation_file.cpp
 msgid "Amount of messages a player may send per 10 seconds."
@@ -2387,7 +2463,6 @@ msgid ""
 "the arm when the camera moves."
 msgstr ""
 "A kar tehetetlensége reálisabb mozgást biztosít\n"
-"a karnak, amikor a kamera mozog.\n"
 "a karnak, amikor a kamera mozog."
 
 #: src/settings_translation_file.cpp
@@ -2408,14 +2483,16 @@ msgid ""
 "optimization.\n"
 "Stated in mapblocks (16 nodes)."
 msgstr ""
-"Ennél a távolságnál a szerver agresszívan optimalizálja, melyik blokkokat "
+"Ennél a távolságnál a szerver agresszívan optimalizálja, hogy melyik "
+"blokkokat\n"
 "küldje a klienseknek.\n"
 "Kis értékek valószínűleg sokat javítanak a teljesítményen, látható "
-"megjelenítési hibák árán.\n"
-"(Néhány víz alatti és barlangokban lévő blokk nem jelenik meg, néha a "
-"felszínen lévők sem.)\n"
-"Ha nagyobb, mint a \"max_block_send_distance\", akkor nincs optimalizáció.\n"
-"A távolság blokkokban értendő (16 node)"
+"megjelenítési\n"
+"hibák árán. (Néhány víz alatti és barlangokban lévő blokk nem jelenik meg,\n"
+"néha a felszínen lévők sem.)\n"
+"Ha ez az érték nagyobb, mint a \"max_block_send_distance\", akkor nincs\n"
+"optimalizáció.\n"
+"A távolság blokkokban értendő (16 node)."
 
 #: src/settings_translation_file.cpp
 msgid "Automatic forward key"
@@ -2438,14 +2515,12 @@ msgid "Autoscaling mode"
 msgstr "Automatikus méretezés mód"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Ugrás gomb"
+msgstr "Aux1 gomb"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Különleges gomb a mászáshoz/ereszkedéshez"
+msgstr "Aux1 gomb a mászáshoz/ereszkedéshez"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2526,6 +2601,12 @@ msgid ""
 "Increasing can reduce artifacting on weaker GPUs.\n"
 "0.1 = Default, 0.25 = Good value for weaker tablets."
 msgstr ""
+"A kamera \"közelségi vágósíkjának\" blokktávolságban mért távolsága 0 és "
+"0,25 között.\n"
+"Csak GLES platformon működik. A legtöbb felhasználó változatlanul "
+"hagyhatja.\n"
+"Növelése csökkentheti a grafikai hibákat a gyengébb GPU-kon.\n"
+"0,1 = alapértelmezett, 0,25 = jóválasztás gyengébb tabletekhez."
 
 #: src/settings_translation_file.cpp
 msgid "Camera smoothing"
@@ -2588,11 +2669,16 @@ msgid ""
 "Center of light curve boost range.\n"
 "Where 0.0 is minimum light level, 1.0 is maximum light level."
 msgstr ""
+"A fénygörbe közepének erősítési tartománya.\n"
+"Ahol 0,0 a minimális fényszint, 1,0 a maximális fényszint."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Sivatag zajának küszöbe"
+msgstr "Csevegésparancs üzeneteinek időkorlátja"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Parancsok"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2611,9 +2697,8 @@ msgid "Chat message count limit"
 msgstr "Csevegőüzenetek számának korlátozása"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat message format"
-msgstr "Üzenet összeomláskor"
+msgstr "Üzenet formátum"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message kick threshold"
@@ -2628,8 +2713,8 @@ msgid "Chat toggle key"
 msgstr "Csevegés váltása gomb"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Parancsok"
+msgid "Chat weblinks"
+msgstr "Internetes linkek a csevegésben"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2647,6 +2732,14 @@ msgstr "Filmszerű mód gomb"
 msgid "Clean transparent textures"
 msgstr "Tiszta átlátszó textúrák"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Kattintható internetes hivatkozások (középső egérkattintás vagy Ctrl+bal "
+"klikk) engedélyezve az elküldött chatüzenetekben."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Kliens"
@@ -2665,7 +2758,7 @@ msgstr "Kliens modolási korlátozások"
 
 #: src/settings_translation_file.cpp
 msgid "Client side node lookup range restriction"
-msgstr ""
+msgstr "A blokk keresési távolság kliensoldali korlátozása"
 
 #: src/settings_translation_file.cpp
 msgid "Climbing speed"
@@ -2692,9 +2785,8 @@ msgid "Colored fog"
 msgstr "Színezett köd"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Színezett köd"
+msgstr "Színezett árnyékok"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2706,6 +2798,14 @@ msgid ""
 "These flags are independent from Minetest versions,\n"
 "so see a full list at https://content.minetest.net/help/content_flags/"
 msgstr ""
+"A tartalomtárban elrejtendő jelölők vesszővel tagolt listája.\n"
+"\"nonfree\" használatával elrejthetők azok a csomagok, amelyek nem tartoznak "
+"a\n"
+"\"szabad szoftverek kategóriájába a Free Software Foundation meghatározása "
+"szerint.\n"
+"Megadhatja továbbá a tartalom besorolásait is.\n"
+"Ezek a jelölők függetlenek a Minetest verziótól, ezért nézze meg\n"
+"a teljes listát itt: https://content.minetest.net/help/content_flags/"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2730,6 +2830,30 @@ msgstr ""
 msgid "Command key"
 msgstr "Parancs gomb"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"A tömörítés foka a térképblokkok lemezre mentéséhez.\n"
+"-1 - alapértelmezett tömörítési fok\n"
+"0 - legkisebb tömörítés, leggyorsabb\n"
+"9 - legjobb tömörítés, leglassabb"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Tömörítés foka a térképblokkok kliensnek küldéséhez.\n"
+"-1 - alapértelmezett tömörítési fok\n"
+"0 - legkisebb tömörítés, leggyorsabb\n"
+"9 - legjobb tömörítés, leglassabb"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Üveg csatlakozása"
@@ -2760,7 +2884,7 @@ msgstr "ContentDB zászló feketelista"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Max Concurrent Downloads"
-msgstr ""
+msgstr "ContentDB egyidejű letöltések maximális száma"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB URL"
@@ -2775,6 +2899,9 @@ msgid ""
 "Continuous forward movement, toggled by autoforward key.\n"
 "Press the autoforward key again or the backwards movement to disable."
 msgstr ""
+"Folyamatos előre mozgás, az \"autoforward\" gomb segítségével.\n"
+"Nyomja meg az \"autoforward\" gombot, vagy a hátrafelé gombot a "
+"kikapcsoláshoz."
 
 #: src/settings_translation_file.cpp
 msgid "Controls"
@@ -2786,12 +2913,12 @@ msgid ""
 "Examples:\n"
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
-"Nappal/éjjel ciklus hossza.\n"
-"Példák: 72 = 20 perc, 360 = 4 perc, 1 = 24 óra, 0 = nappal/éjjel/bármelyik "
+"Nappal/éjjel ciklus hosszát határozza meg.\n"
+"Példák:\n"
+"72 = 20 perc, 360 = 4 perc, 1 = 24 óra, 0 = nappal/éjjel/bármelyik "
 "változatlan marad."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Controls sinking speed in liquid."
 msgstr "Folyadékban a süllyedési sebességet szabályozza."
 
@@ -2809,6 +2936,10 @@ msgid ""
 "Value >= 10.0 completely disables generation of tunnels and avoids the\n"
 "intensive noise calculations."
 msgstr ""
+"A csatornák szélességét irányítja, a kisebb érték szélesebb csatornát hoz "
+"létre.\n"
+"Érték >= 10.0 teljesen kikapcsolja a csatornák generálását és elkerüli az\n"
+"intenzív zajszámítást."
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
@@ -2823,11 +2954,12 @@ msgid "Crosshair alpha"
 msgstr "Célkereszt átlátszóság"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
-msgstr "Célkereszt átlátszóság (0 és 255 között)."
+"This also applies to the object crosshair."
+msgstr ""
+"Célkereszt átlátszóság (0 és 255 között).\n"
+"Az objektum célkereszt színét is meghatározza."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2838,6 +2970,8 @@ msgid ""
 "Crosshair color (R,G,B).\n"
 "Also controls the object crosshair color"
 msgstr ""
+"Célkereszt szín (R,G,B).\n"
+"Az objektum célkereszt színét is állítja"
 
 #: src/settings_translation_file.cpp
 msgid "DPI"
@@ -2852,9 +2986,8 @@ msgid "Debug info toggle key"
 msgstr "Hibakereső információra váltás gomb"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Debug log file size threshold"
-msgstr "Sivatag zajának küszöbszintje"
+msgstr "Hibakeresési naplófájl méretküszöbe"
 
 #: src/settings_translation_file.cpp
 msgid "Debug log level"
@@ -2901,16 +3034,18 @@ msgid "Default report format"
 msgstr "Alapértelmezett jelentésformátum"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Default stack size"
-msgstr "Alapértelmezett játék"
+msgstr "Alapértelmezett kötegméret"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Árnyékszűrők minőségének beállítása.\n"
+"Lágy árnyék effektus szimulálása PCF vagy Poisson disk eljárással,\n"
+"de egyéb erőforrásokat is használ."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -2922,20 +3057,17 @@ msgstr "A homokos tengerpartok területeit határozza meg."
 
 #: src/settings_translation_file.cpp
 msgid "Defines distribution of higher terrain and steepness of cliffs."
-msgstr ""
-"A magasabb terep (hegytetők) területeit szabja meg és a szirtek\n"
-"meredekségére is hatással van."
+msgstr "A magasabb terep eloszlását, a szirtek meredekségét szabályozza."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines distribution of higher terrain."
-msgstr "A \"terrain_higher\" területeit határozza meg (hegytetők terepe)."
+msgstr "A magasabb területek eloszlását határozza meg."
 
 #: src/settings_translation_file.cpp
 msgid "Defines full size of caverns, smaller values create larger caverns."
 msgstr ""
-"Az üregek teljes méretét adja meg. Kisebb értékek nagyobb\n"
-"üregeket képeznek."
+"Az üregek teljes méretét adja meg, a kisebb értékek nagyobb üregeket "
+"képeznek."
 
 #: src/settings_translation_file.cpp
 msgid "Defines large-scale river channel structure."
@@ -2956,8 +3088,7 @@ msgstr "A folyómedrek mélységét határozza meg."
 #: src/settings_translation_file.cpp
 msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
 msgstr ""
-"A maximális távolság, aminél a játékosok látják egymást,\n"
-"blokkokban megadva (0 = korlátlan)."
+"A maximális játékos küldési távolság blokkokban megadva (0 = korlátlan)."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the width of the river channel."
@@ -3024,9 +3155,8 @@ msgid "Desynchronize block animation"
 msgstr "Blokkanimáció deszinkronizálása"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dig key"
-msgstr "Jobb gomb"
+msgstr "Ásás gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3040,6 +3170,10 @@ msgstr "Csalás elleni védelem letiltása"
 msgid "Disallow empty passwords"
 msgstr "Üres jelszavak tiltása"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Képsűrűség méretezési faktor"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "A szerver domain neve, ami a szerverlistában megjelenik."
@@ -3061,12 +3195,10 @@ msgid "Dump the mapgen debug information."
 msgstr "A térképgenerátor hibakeresési információinak kiírása."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dungeon maximum Y"
-msgstr "Tömlöc  maximális Y magassága"
+msgstr "Tömlöc maximális Y magassága"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dungeon minimum Y"
 msgstr "Tömlöc minimális Y magassága"
 
@@ -3079,6 +3211,8 @@ msgid ""
 "Enable IPv6 support (for both client and server).\n"
 "Required for IPv6 connections to work at all."
 msgstr ""
+"IPv6 támogatás engedélyezése (a kliens és a szerver számára is).\n"
+"Szükséges, hogy az IPv6 kapcsolatok egyáltalán működjenek."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3090,21 +3224,32 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Poisson disk szűrés engedélyezése.\n"
+"Igazra állítás esetén Poisson disk eljárással képez lágy árnyékokat. "
+"Különben a PCF szűrőt használja."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Színes árnyékok engedélyezése.\n"
+"Igaz érték esetén áttettsző blokkok színes árnyékot vethetnek. "
+"Erőforrásigényes."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
 msgstr "Konzolablak engedélyezése"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable creative mode for all players"
-msgstr "Kreatív mód engedélyezése az Ãºjonnan létrehozott térképekhez."
+msgstr "Kreatív mód engedélyezése az Ã¶sszes játékos számára"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable joysticks"
 msgstr "Joystick engedélyezése"
 
@@ -3120,13 +3265,6 @@ msgstr "Mod biztonság engedélyezése"
 msgid "Enable players getting damage and dying."
 msgstr "Játékosok sérülésének és halálának engedélyezése."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3134,25 +3272,24 @@ msgstr ""
 "használható)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable register confirmation"
-msgstr "Regisztermegerősítés engedélyezése"
+msgstr "Regisztráció megerősítés engedélyezése"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Enable register confirmation when connecting to server.\n"
 "If disabled, new account will be registered automatically."
 msgstr ""
-"Engedélyezze a regisztráció megerősítését, amikor csatlakozik a szerverhez.\n"
-"Letiltás esetén az új fiók automatikusan regisztrálásra kerül."
+"Ha be van kapcsolva, a regisztráció megerősítését kéri, amikor csatlakozik "
+"egy szerverhez.\n"
+"Ha ki van kapcsolva, az új fiók automatikusan regisztrálásra kerül."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable smooth lighting with simple ambient occlusion.\n"
 "Disable for speed or for different looks."
 msgstr ""
-"A simított megvilágítás engedélyezése egyszerű ambient occlusion-nel.\n"
+"A simított megvilágítás engedélyezése egyszerű környezeti árnyékolással.\n"
 "A sebesség érdekében vagy másféle kinézetért kikapcsolhatod."
 
 #: src/settings_translation_file.cpp
@@ -3185,27 +3322,27 @@ msgid ""
 "Enable vertex buffer objects.\n"
 "This should greatly improve graphics performance."
 msgstr ""
+"Vertex buffer objektumok engedélyezése.\n"
+"Ez nagyban javíthatja a grafikus teljesítményt."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable view bobbing and amount of view bobbing.\n"
 "For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
 msgstr ""
-"Bekapcsolja a fejmozgást és beállítja a mértékét.\n"
+"Bekapcsolja a fejbillegést és beállítja a mértékét.\n"
 "Pl: 0 nincs fejmozgás; 1.0 alapértelmezett fejmozgás van; 2.0 dupla "
-"fejmozgás van"
+"fejmozgás van."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Enable/disable running an IPv6 server.\n"
 "Ignored if bind_address is set.\n"
 "Needs enable_ipv6 to be enabled."
 msgstr ""
-"IPv6 szerver futtatásának engedélyezése/letiltása. Egy IPv6 szerver "
-"lehetséges, hogy\n"
-"IPv6 kliensekre van korlátozva, a rendszer konfigurációtól függően.\n"
-"Nincs figyelembe véve, ha bind_address van beállítva."
+"IPv6 szerver futtatásának engedélyezése/letiltása.\n"
+"Nincs figyelembe véve, ha bind_address van beállítva.\n"
+"Szükséges hozzá, hogy az ipv6 engedélyezve legyen."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3214,15 +3351,18 @@ msgid ""
 "appearance of high dynamic range images. Mid-range contrast is slightly\n"
 "enhanced, highlights and shadows are gradually compressed."
 msgstr ""
+"Engedélyezi Hable 'Uncharted 2' színtónusleképezését.\n"
+"A fotófilmek színgörbéjét szimulálja és utánozza a nagy dinamikatartományú\n"
+"képi megjelenést. A közepző színtartomány kontrasztját kissé\n"
+"erősíti, a világosabb és sötétebb részeket fokozatosan tömöríti."
 
 #: src/settings_translation_file.cpp
 msgid "Enables animation of inventory items."
-msgstr "Az eszköztárelemek animációjának engedélyezése."
+msgstr "Az felszerelésben lévő tárgyak animációjának engedélyezése."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enables caching of facedir rotated meshes."
-msgstr "Engedélyezi az elforgatott rácsvonalak gyorsítótárazását."
+msgstr "Az elforgatott hálók irányának gyorsítótárazásának engedélyezése."
 
 #: src/settings_translation_file.cpp
 msgid "Enables minimap."
@@ -3235,15 +3375,29 @@ msgid ""
 "sound controls will be non-functional.\n"
 "Changing this setting requires a restart."
 msgstr ""
+"Engedélyezi a hangrendszert.\n"
+"Ha ki van kapcsolva, teljesen kikapcsol minden hangot és a játék "
+"hangvezérlői\n"
+"nem fognak működni.\n"
+"Ennek a beállításnak a megváltoztatása a játék újraindítását igényli."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+"Engedélyez olyan kompromisszimus megoldásokat, amelyek csökkentik a CPU "
+"terhelését vagy\n"
+"növelik a renderelési teljesítményt kisebb vizuális hibák árán, amelyek nem "
+"befolyásolják a játszhatóságot."
 
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Játékmotor profiler adatok kiírási időköze"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Entity methods"
-msgstr "Egység módszerek"
+msgstr "Entitás metódusok"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3254,29 +3408,33 @@ msgid ""
 "Values < 1.0 (for example 0.25) create a more defined surface level with\n"
 "flatter lowlands, suitable for a solid floatland layer."
 msgstr ""
+"A lebegő földek vékonyításának kitevője. A vékonyítás módján változtat.\n"
+"Érték = 1,0 egyeneletes, lineáris vékonyítás.\n"
+"Értékek > 1,0 az alapértelmezett különálló lebegő földekhez illő könnyed\n"
+"vékonyítás.\n"
+"Értékek < 1,0 (például 0,25) határozottab felszínt képez laposabb "
+"alföldekkel,\n"
+"egybefüggű lebegő föld réteghez használható."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "FPS when unfocused or paused"
-msgstr "Maximum FPS a játék szüneteltetésekor."
+msgstr "FPS, amikor a játék meg van állítva, vagy nincs fókuszban"
 
 #: src/settings_translation_file.cpp
 msgid "FSAA"
 msgstr "FSAA"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Factor noise"
 msgstr "Tényezőzaj"
 
 #: src/settings_translation_file.cpp
 msgid "Fall bobbing factor"
-msgstr ""
+msgstr "Leesés utáni fejrázkódási tényező"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Fallback font path"
-msgstr "Tartalék betűtípus"
+msgstr "Tartalék betűtípus útvonala"
 
 #: src/settings_translation_file.cpp
 msgid "Fast key"
@@ -3295,12 +3453,11 @@ msgid "Fast movement"
 msgstr "Gyors mozgás"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Gyors mozgás (a használat gombbal).\n"
+"Gyors mozgás (az \"Aux1\" gombbal).\n"
 "Szükséges hozzá a gyors mód jogosultság a szerveren."
 
 #: src/settings_translation_file.cpp
@@ -3312,14 +3469,14 @@ msgid "Field of view in degrees."
 msgstr "Látóterület fokokban."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "File in client/serverlist/ that contains your favorite servers displayed in "
 "the\n"
 "Multiplayer Tab."
 msgstr ""
 "A client/serverlist/ mappában lévő fájl, ami tartalmazza a kedvenc "
-"szervereket, amik a Többjátékos fül alatt jelennek meg."
+"szervereidet,\n"
+"amik a Többjátékos fül alatt jelennek meg."
 
 #: src/settings_translation_file.cpp
 msgid "Filler depth"
@@ -3340,6 +3497,14 @@ msgid ""
 "light edges to transparent textures. Apply a filter to clean that up\n"
 "at texture load time. This is automatically enabled if mipmapping is enabled."
 msgstr ""
+"A szűrt textúrák vegyíthetik a teljesen átlátszó szomszédokkal rendelkező "
+"RGB értékeket,\n"
+"amit a PNG optimalizálók általában figyelmen kívül hagynak, és ez gyakran "
+"sötét vagy\n"
+"világos élekhez vezet az átlátszó textúráknál. Használjon szűrőt ezeknek a "
+"textúra betöltésekor\n"
+"történő eltüntetésére. Ez automatikusan bekapcsol, ha a mipmapping be van "
+"kapcsolva."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3348,17 +3513,19 @@ msgstr "Szűrés"
 #: src/settings_translation_file.cpp
 msgid "First of 4 2D noises that together define hill/mountain range height."
 msgstr ""
+"Az első a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/"
+"hegységek magasságát."
 
 #: src/settings_translation_file.cpp
 msgid "First of two 3D noises that together define tunnels."
 msgstr ""
+"Az első a két 3D zajból, amelyek együttesen meghatározzák az alagutakat."
 
 #: src/settings_translation_file.cpp
 msgid "Fixed map seed"
 msgstr "Fix térkép seed"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Fixed virtual joystick"
 msgstr "Rögzített virtuális joystick"
 
@@ -3376,16 +3543,15 @@ msgstr "Lebegő földek minimális Y magassága"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland noise"
-msgstr "Lebegőföldek zaja"
+msgstr "Lebegő földek zaja"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland taper exponent"
-msgstr "A lebegő hegyek alapzaja"
+msgstr "A lebegő földek kúpkitevője"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland tapering distance"
-msgstr "A lebegő földek hegyeinek távolsága"
+msgstr "A lebegő földek kúpjainak távolsága"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland water level"
@@ -3432,21 +3598,46 @@ msgid "Font size"
 msgstr "Betűtípus mérete"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
-msgstr ""
+msgid "Font size divisible by"
+msgstr "Betűméret osztója"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
+"Az alapértelmezett betűtípus betűmérete, ahol 1 egység = 1 pixel 96 DPI "
+"esetén"
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "A monospace betűtípus betűmérete, ahol 1 egység = 1 pixel 96 DPI esetén"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Font size of the recent chat text and chat prompt in point (pt).\n"
 "Value 0 will use the default font size."
 msgstr ""
+"A legutóbbi csevegésszövegek és üzenetek betűmérete pontban (pt).\n"
+"0 érték esetén az alapértelmezett betűméretet fogja használni."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+"A pixeles stílusú betűtípusokhoz, amelyek nem méretezhetők olyan jól, ez "
+"biztosítja, hogy a használt\n"
+"betűméretek az ilyen betűtípus esetén mindig oszthatók legyenek ezzel az "
+"értékkel, pixelben. Például\n"
+"egy 16 pixel magas pixeles stílusú betűtípus esetén ezt 16-ra kell állítani, "
+"ezáltal csak 16, 32, 48 stb.\n"
+"lesz használható, ezért ha egy mod 25-ös méretet igényel, 32-est fog kapni."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Format of player chat messages. The following strings are valid "
 "placeholders:\n"
@@ -3454,7 +3645,7 @@ msgid ""
 msgstr ""
 "A játékos csevegési üzeneteinek formátuma. A következő karakterláncok "
 "érvényesek:\n"
-"@ név, @ üzenet, @ időbélyeg (opcionális)"
+"@név, @üzenet, @időbélyeg (opcionális)"
 
 #: src/settings_translation_file.cpp
 msgid "Format of screenshots."
@@ -3462,36 +3653,34 @@ msgstr "Képernyőmentések formátuma."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Color"
-msgstr ""
+msgstr "Formspec panelek alapértelmezett háttérszíne"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Opacity"
-msgstr ""
+msgstr "Formspec panelek hátterének alapértelmezett átlátszósága"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Color"
-msgstr ""
+msgstr "Teljes képernyős Formspec panelek háttérszíne"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Opacity"
-msgstr ""
+msgstr "Teljes képernyős Formspec panelek hátterének átlátszósága"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Formspec default background color (R,G,B)."
-msgstr "Játékon belüli csevegő konzol hátterének színe (R,G,B)."
+msgstr "Formspec panelek alapértelmezett háttérszíne (R,G,B)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Formspec default background opacity (between 0 and 255)."
 msgstr ""
-"Játékon belüli csevegő konzol hátterének alfája (átlátszatlanság, 0 és 255 "
+"Játékon belüli kezelőpanelek hátterének alfája (átlátszatlanság, 0 és 255 "
 "között)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Formspec full-screen background color (R,G,B)."
-msgstr "Játékon belüli csevegő konzol hátterének színe (R,G,B)."
+msgstr ""
+"Játékon belüli teljes képrenyős kezelőpanelek hátterének színe (R,G,B)."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec full-screen background opacity (between 0 and 255)."
@@ -3505,6 +3694,8 @@ msgstr "Előre gomb"
 #: src/settings_translation_file.cpp
 msgid "Fourth of 4 2D noises that together define hill/mountain range height."
 msgstr ""
+"A negyedik a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/"
+"hegységek magasságát."
 
 #: src/settings_translation_file.cpp
 msgid "Fractal type"
@@ -3512,11 +3703,7 @@ msgstr "Fraktál típusa"
 
 #: src/settings_translation_file.cpp
 msgid "Fraction of the visible distance at which fog starts to be rendered"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "FreeType betűtípusok"
+msgstr "A látótávolságnak az a része, amelynél a köd renderelése kezdődik"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3541,6 +3728,14 @@ msgid ""
 "to maintain active objects up to this distance in the direction the\n"
 "player is looking. (This can avoid mobs suddenly disappearing from view)"
 msgstr ""
+"Mekkora távolságból észleljék a kliensek az objektumokat, térképblokkokban "
+"mérve (16 blokk).\n"
+"\n"
+"Ha nagyobbra van állítva, mint az active_block_range, akkor a szervert arra "
+"kényszeríti, hogy\n"
+"az aktív objektumokat betöltve tartsa eddig a távolságig a játékos "
+"tekintetének irányában.\n"
+"(Ez megakadályozza, hogy a mobok hirtelen eltűnjenek a látómezőből)"
 
 #: src/settings_translation_file.cpp
 msgid "Full screen"
@@ -3563,36 +3758,36 @@ msgid "GUI scaling filter txr2img"
 msgstr "Felhasználói felület méretarány szűrő txr2img"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Global callbacks"
-msgstr "Globális visszahívások"
+msgstr "Globális visszatérések"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
-"Térkép generálási jellemzők csak a Flat (lapos) térképgenerátor esetében.\n"
-"Esetenkénti tavak és dombok generálása a lapos világba.\n"
-"The default flags set in the engine are: none\n"
-"The flags string modifies the engine defaults.\n"
-"Flags that are not specified in the flag string are not modified from the "
-"default.\n"
-"Flags starting with \"no\" are used to explicitly disable them."
+"Globális térképgenerálási jellemzők.\n"
+"A Mapgen v6 térképgenerátorban a 'decorations' jelző szabályozza az összes "
+"dekorációt,\n"
+"kivéve a fákat és a dzsungelfüvet, a többi térképgenerátornál pedig az "
+"összeset."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Gradient of light curve at maximum light level.\n"
 "Controls the contrast of the highest light levels."
 msgstr ""
+"A fénygörbe gradiense a legmagasabb fényszinten.\n"
+"A legmagasabb fényszintek kontrasztrját szabályozza."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Gradient of light curve at minimum light level.\n"
 "Controls the contrast of the lowest light levels."
 msgstr ""
+"A fénygörbe gradiense a legalacsonyabb fényszinten.\n"
+"A legalacsonyabb fényszintek kontrasztrját szabályozza."
 
 #: src/settings_translation_file.cpp
 msgid "Graphics"
@@ -3611,7 +3806,6 @@ msgid "Ground noise"
 msgstr "Talaj zaj"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "HTTP mods"
 msgstr "HTTP Modok"
 
@@ -3624,19 +3818,17 @@ msgid "HUD toggle key"
 msgstr "HUD váltás gomb"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Handling for deprecated Lua API calls:\n"
 "-    none: Do not log deprecated calls\n"
 "-    log: mimic and log backtrace of deprecated call (default).\n"
 "-    error: abort on usage of deprecated call (suggested for mod developers)."
 msgstr ""
-"Az elavult lua API hívások kezelése:\n"
-"-örökölt: (próbálja meg) a régi viselkedést utánozni (alapértelmezett).\n"
-"-log: elavult hívás visszakövetése és naplózása (hibakereséshez "
-"alapértelmezett).\n"
-"-error: Megszakítja az elavult hívás használatát (javasolt a mod "
-"fejlesztőknek)."
+"Az elavult Lua API hívások kezelése:\n"
+"-none: ne naplózza az elavult hívásokat\n"
+"-log: elavult hívás utánozása és naplózása (alapértelmezett).\n"
+"-error: megszakítja az elavult hívás használatát (javasolt a "
+"modfejlesztőknek)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3646,6 +3838,11 @@ msgid ""
 "call).\n"
 "* Instrument the sampler being used to update the statistics."
 msgstr ""
+"Hagyja, hogy a profiler behangolja magát:\n"
+"* Üres függvény behangolása.\n"
+"Ezáltal mérhető, hogy a hangolás maga mennyi időbe telik (+1 függvényhívás)."
+"\n"
+"* A mintavevő hangolása a mutatószámok frissítésehez."
 
 #: src/settings_translation_file.cpp
 msgid "Heat blend noise"
@@ -3656,10 +3853,10 @@ msgid "Heat noise"
 msgstr "Hőzaj"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "A kezdeti ablak magassága."
+msgstr ""
+"A kezdőablak magassága. Teljes képernyős módban nem kerül figyelmbe vételre."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3698,167 +3895,164 @@ msgid "Homepage of server, to be displayed in the serverlist."
 msgstr "A szerver honlapja, ami a szerverlistában megjelenik."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Horizontal acceleration in air when jumping or falling,\n"
 "in nodes per second per second."
 msgstr ""
 "Vízszintes gyorsulás a levegőben ugráskor vagy leeséskor,\n"
-"blokk/másodpercben"
+"node/másodperc/másodpercben."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Horizontal and vertical acceleration in fast mode,\n"
 "in nodes per second per second."
 msgstr ""
 "Vízszintes és függőleges gyorsulás gyors módban,\n"
-"blokk/másodpercben."
+"node/másodperc/másodpercben."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Horizontal and vertical acceleration on ground or when climbing,\n"
 "in nodes per second per second."
-msgstr "Vízszintes és függőleges gyorsulás a földön, blokk/másodpercben."
+msgstr ""
+"Vízszintes és függőleges gyorsulás a földön, vagy mászáskor,\n"
+"node/másodpercben."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar next key"
-msgstr "Gyorsgomb következő gomb"
+msgstr "Gyorselérési sáv következő gomb"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Hotbar previous key"
-msgstr "Gyorsgomb előző gomb"
+msgstr "Gyorselérési sáv előző gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 1 key"
-msgstr ""
+msgstr "Gyorselérési sáv 1-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 10 key"
-msgstr ""
+msgstr "Gyorselérési sáv 10-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 11 key"
-msgstr ""
+msgstr "Gyorselérési sáv 11-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 12 key"
-msgstr ""
+msgstr "Gyorselérési sáv 12-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 13 key"
-msgstr ""
+msgstr "Gyorselérési sáv 13-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 14 key"
-msgstr ""
+msgstr "Gyorselérési sáv 14-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 15 key"
-msgstr ""
+msgstr "Gyorselérési sáv 15-ös hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 16 key"
-msgstr ""
+msgstr "Gyorselérési sáv 16-os hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 17 key"
-msgstr ""
+msgstr "Gyorselérési sáv 17-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 18 key"
-msgstr ""
+msgstr "Gyorselérési sáv 18-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 19 key"
-msgstr ""
+msgstr "Gyorselérési sáv 19-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 2 key"
-msgstr ""
+msgstr "Gyorselérési sáv 2-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 20 key"
-msgstr ""
+msgstr "Gyorselérési sáv 20-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 21 key"
-msgstr ""
+msgstr "Gyorselérési sáv 21-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 22 key"
-msgstr ""
+msgstr "Gyorselérési sáv 22-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 23 key"
-msgstr ""
+msgstr "Gyorselérési sáv 23-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 24 key"
-msgstr ""
+msgstr "Gyorselérési sáv 24-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 25 key"
-msgstr ""
+msgstr "Gyorselérési sáv 25-ös hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 26 key"
-msgstr ""
+msgstr "Gyorselérési sáv 26-os hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 27 key"
-msgstr ""
+msgstr "Gyorselérési sáv 27-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 28 key"
-msgstr ""
+msgstr "Gyorselérési sáv 28-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 29 key"
-msgstr ""
+msgstr "Gyorselérési sáv 29-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 3 key"
-msgstr ""
+msgstr "Gyorselérési sáv 3-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 30 key"
-msgstr ""
+msgstr "Gyorselérési sáv 30-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 31 key"
-msgstr ""
+msgstr "Gyorselérési sáv 31-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 32 key"
-msgstr ""
+msgstr "Gyorselérési sáv 32-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 4 key"
-msgstr ""
+msgstr "Gyorselérési sáv 4-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 5 key"
-msgstr ""
+msgstr "Gyorselérési sáv 5-ös hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 6 key"
-msgstr ""
+msgstr "Gyorselérési sáv 6-os hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 7 key"
-msgstr ""
+msgstr "Gyorselérési sáv 7-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 8 key"
-msgstr ""
+msgstr "Gyorselérési sáv 8-as hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 9 key"
-msgstr ""
+msgstr "Gyorselérési sáv 9-es hely gomb"
 
 #: src/settings_translation_file.cpp
 msgid "How deep to make rivers."
@@ -3870,13 +4064,16 @@ msgid ""
 "If negative, liquid waves will move backwards.\n"
 "Requires waving liquids to be enabled."
 msgstr ""
+"Milyen gyorsan mozognak a folyadékhullámok. Magasabb = gyorsabb.\n"
+"Ha negatív, a folyadékhullámok hátrafelé mozognak.\n"
+"A hullámzó folyadékokat engedélyezni kell hozzá."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "How much the server will wait before unloading unused mapblocks.\n"
 "Higher value is smoother, but will use more RAM."
 msgstr ""
-"Mennyi ideig vár a szerver, mielőtt betöltetlenné teszi a nem használt "
+"Mennyi ideig vár a szerver, mielőtt eltávolítja a memóriából a nem használt "
 "térképblokkokat.\n"
 "Magasabb érték egyenletesebb, de több RAM-ot használ."
 
@@ -3889,9 +4086,8 @@ msgid "Humidity blend noise"
 msgstr "Páratartalom keverés zaj"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Humidity noise"
-msgstr "Páratartalomzaj"
+msgstr "Páratartalom zaj"
 
 #: src/settings_translation_file.cpp
 msgid "Humidity variation for biomes."
@@ -3914,13 +4110,11 @@ msgstr ""
 "hogy ne pazaroljon CPU erőforrást feleslegesen."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Ha le van tiltva, a használat (use) gomb lesz használatban a gyors "
-"repüléshez,\n"
+"Ha le van tiltva, az \"Aux1\" gomb lesz használatban a gyors repüléshez,\n"
 "ha a repülés és a gyors mód is engedélyezve van."
 
 #: src/settings_translation_file.cpp
@@ -3931,6 +4125,10 @@ msgid ""
 "invisible\n"
 "so that the utility of noclip mode is reduced."
 msgstr ""
+"Ha engedélyezve, a szerver kiválogatja a takarásban lévő térképblokkokat\n"
+"a játékos szemszögének megfelelően. Ezáltal a kliensnek küldött blokkok\n"
+"száma 50-80%-kal csökkenthető. A klines nem kapja ezentúl a legtöbb nem\n"
+"látható blokkot, emiatt a noclip mód (falonátjárás) kevésbé lesz használható."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3942,23 +4140,23 @@ msgstr ""
 "node-okon. Szükséges hozzá a noclip jogosultság a szerveren."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Ha engedélyezve van, a \"használat\" (use) gomb lesz használatban a "
-"\"lopakodás\" (sneak) helyett lefelé mászáskor, vagy ereszkedéskor."
+"Ha engedélyezve van, az \"Aux1\"gomb lesz használatban a \"lopakodás"
+"\" (sneak) helyett lefelé mászáskor,\n"
+"vagy ereszkedéskor."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, actions are recorded for rollback.\n"
 "This option is only read when server starts."
 msgstr ""
-"Ha engedélyezve van, akkor a műveleteket rögzíti a visszagörgetéshez.\n"
-"Ez az opció csak akkor olvasható, amikor a szerver elindul."
+"Ha engedélyezve van, akkor a műveletek rögzülnek a visszavonhatóság "
+"érdekében.\n"
+"Ez az opció csak akkor van beolvasva, amikor a szerver elindul."
 
 #: src/settings_translation_file.cpp
 msgid "If enabled, disable cheat prevention in multiplayer."
@@ -4001,12 +4199,19 @@ msgid ""
 "limited\n"
 "to this distance from the player to the node."
 msgstr ""
+"Ha a CSM korlátozás be van kapcsolva az aktív blokktávolságra, akkor a "
+"get_node\n"
+"hívások korlátozva lesznek a játkostól e távolságon belül található "
+"blokkokra."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Ha egy parancs végrehajtása tovább tart, mint az itt másodpercben megadott "
+"idő,\n"
+"az időadatok hozzá lesznek fűzve a parancs visszajelző üzenetéhez"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4015,6 +4220,10 @@ msgid ""
 "deleting an older debug.txt.1 if it exists.\n"
 "debug.txt is only moved if this setting is positive."
 msgstr ""
+"Ha a debug.txt fájlmérete megabájtban meghaladja megnyitáskor az itt \n"
+"megadott számot, a fájl átnevezésre kerül debug.txt.1-re,\n"
+"és ha létezett egy régebbi debug.txt.1, az törlésre kerül.\n"
+"A debug.txt csak akkor lesz átnevezve, ha ez a beállítás engedélyzve van."
 
 #: src/settings_translation_file.cpp
 msgid "If this is set, players will always (re)spawn at the given position."
@@ -4057,34 +4266,39 @@ msgid ""
 "Instrument builtin.\n"
 "This is usually only needed by core/builtin contributors"
 msgstr ""
+"Beépülő behangolása.\n"
+"Erre általában csak core/builtin közreműködőknek van szükségük"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
-msgstr "Csevegésparancsok bemutatása regisztrációkor."
+msgid "Instrument chat commands on registration."
+msgstr "Csevegésparancsok behangolása regisztrációkor."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Instrument global callback functions on registration.\n"
 "(anything you pass to a minetest.register_*() function)"
 msgstr ""
+"A globális callback függvények behangolása regisztrációkor.\n"
+"(bármi, amit átadsz egy minetest.register_*() függvénynek)"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Instrument the action function of Active Block Modifiers on registration."
-msgstr ""
+msgstr "Az Aktív blokk módosítók akciófüggvényének behangolása regisztrációkor."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Instrument the action function of Loading Block Modifiers on registration."
 msgstr ""
+"A Betöltendő blokk módosítók akciófüggvényének behangolása regisztrációkor."
 
 #: src/settings_translation_file.cpp
 msgid "Instrument the methods of entities on registration."
-msgstr ""
+msgstr "Az entitások metódusainak hangolása regisztrációkor."
 
 #: src/settings_translation_file.cpp
 msgid "Instrumentation"
-msgstr ""
+msgstr "Behangolás"
 
 #: src/settings_translation_file.cpp
 msgid "Interval of saving important changes in the world, stated in seconds."
@@ -4093,15 +4307,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Interval of sending time of day to clients."
-msgstr ""
+msgstr "A napszak kliensnek való küldésének gyakorisága."
 
 #: src/settings_translation_file.cpp
 msgid "Inventory items animations"
-msgstr "Eszköztár elemek animációi"
+msgstr "Felszerelésben lévő tárgyak animációi"
 
 #: src/settings_translation_file.cpp
 msgid "Inventory key"
-msgstr "Eszköztár gomb"
+msgstr "Felszerelés gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Invert mouse"
@@ -4120,12 +4334,10 @@ msgid "Italic monospace font path"
 msgstr "Dőlt monspace betűtípus útvonal"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Item entity TTL"
 msgstr "Elem entitás TTL"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Iterations"
 msgstr "Ismétlések"
 
@@ -4151,13 +4363,12 @@ msgid "Joystick button repetition interval"
 msgstr "Joystick gomb ismétlési időköz"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Joystick deadzone"
-msgstr "Joystick típus"
+msgid "Joystick dead zone"
+msgstr "Joystick holttér"
 
 #: src/settings_translation_file.cpp
 msgid "Joystick frustum sensitivity"
-msgstr "Joystick frustum érzékenység"
+msgstr "Joystick látómező érzékenység"
 
 #: src/settings_translation_file.cpp
 msgid "Joystick type"
@@ -4202,15 +4413,14 @@ msgstr ""
 "Tartomány nagyjából -2 és 2 között."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Julia set only.\n"
 "Z component of hypercomplex constant.\n"
 "Alters the shape of the fractal.\n"
 "Range roughly -2 to 2."
 msgstr ""
-"Julia-halmaz.\n"
-"Z komponens hiperkomplex konstans.\n"
+"Csak Julia-halmaz.\n"
+"Hiperkomplex állandó Z összetevője.\n"
 "Megváltoztatja a fraktál alakját.\n"
 "Tartomány nagyjából -2 és 2 között."
 
@@ -4259,13 +4469,12 @@ msgstr ""
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Key for digging.\n"
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Gomb az ugráshoz.\n"
+"Gomb az ásáshoz.\n"
 "Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4338,7 +4547,7 @@ msgid ""
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
 "Gomb a játékos előre mozgásához.\n"
-"Lásd:  http://irrlicht.sourceforge.net/docu/namespaceirr."
+"Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
@@ -4407,18 +4616,17 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Gomb az eszköztár megnyitásához.\n"
+"Gomb a felszerelés megnyitásához.\n"
 "Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Key for placing.\n"
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Gomb az ugráshoz.\n"
+"Gomb az elhelyezéshez.\n"
 "Lásd: http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4932,6 +5140,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"A profiler kijelzőjének kapcsológombja. Fejlesztéshez használatos.\n"
+"Lásd http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5018,6 +5229,9 @@ msgid ""
 "updated over\n"
 "network."
 msgstr ""
+"A szerver órajelének hossza és az az intervallum, amely alatt az "
+"objektumokat általánosan\n"
+"frissíti a hálózaton."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5028,17 +5242,16 @@ msgstr ""
 "A hullámzó folyadékok engedélyezése szükséges hozzá."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Length of time between Active Block Modifier (ABM) execution cycles"
 msgstr "Az Aktív Blokk módosító (ABM) végrehajtási ciklusok közötti időtartam"
 
 #: src/settings_translation_file.cpp
 msgid "Length of time between NodeTimer execution cycles"
-msgstr ""
+msgstr "Két NodeTimer végrehajtás között eltelt idő"
 
 #: src/settings_translation_file.cpp
 msgid "Length of time between active block management cycles"
-msgstr ""
+msgstr "Két aktív blokk kezelési fázis között eltelt idő"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5062,27 +5275,27 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Light curve boost"
-msgstr ""
+msgstr "Fénygörbe kiemelés"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve boost center"
-msgstr ""
+msgstr "Fénygörbe kiemelés középpontja"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve boost spread"
-msgstr ""
+msgstr "Fénygörbe kiemelés kiterjedése"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve gamma"
-msgstr ""
+msgstr "Fénygörbe kiemelés gammája"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve high gradient"
-msgstr ""
+msgstr "A fénygörbe tetejének gradiense"
 
 #: src/settings_translation_file.cpp
 msgid "Light curve low gradient"
-msgstr ""
+msgstr "A fénygörbe aljának gradiense"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5090,6 +5303,11 @@ msgid ""
 "Only mapchunks completely within the mapgen limit are generated.\n"
 "Value is stored per-world."
 msgstr ""
+"A térképgenerálás határa, node-okban, mind a 6 irányban a (0, 0, 0) "
+"pozíciótól kezdve.\n"
+"Csak a teljesen a térképgenerálási határon belül lévő térképdarabkák "
+"generálódnak le.\n"
+"Az érték világonként külön tárolódik."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5099,6 +5317,11 @@ msgid ""
 "-    Downloads performed by main menu (e.g. mod manager).\n"
 "Only has an effect if compiled with cURL."
 msgstr ""
+"A párhzamos HTTP-kérések számának korlátja. Hatása:\n"
+"-    Médialekérések, ha a szerver remote_media beállítást használ.\n"
+"-    Szerverlista letöltés és szerverközzététel.\n"
+"-    Letöltések a főmenüből (pl. mod manager).\n"
+"Csak akkor van hatása, ha cURL-lel lett összeállítva."
 
 #: src/settings_translation_file.cpp
 msgid "Liquid fluidity"
@@ -5114,15 +5337,13 @@ msgstr "Folyadékhullámzás maximum"
 
 #: src/settings_translation_file.cpp
 msgid "Liquid queue purge time"
-msgstr ""
+msgstr "Folyadék sortisztítási ideje"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Liquid sinking"
 msgstr "Folyadék süllyedés"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Liquid update interval in seconds."
 msgstr "A folyadékok frissítési időköze másodpercben."
 
@@ -5140,13 +5361,16 @@ msgid ""
 "Provides a /profiler command to access the compiled profile.\n"
 "Useful for mod developers and server operators."
 msgstr ""
+"A játék profiler betöltése hogy játékprofílozási adatokat gyűjtsön.\n"
+"Elérhetővé teszi a /profiler parancsot, amellyel elérhetők az összeállított "
+"profilok.\n"
+"Hasznos lehet mod fejelsztőknek és szerver üzemeltetőknek."
 
 #: src/settings_translation_file.cpp
 msgid "Loading Block Modifiers"
-msgstr "Blokk módosítók betöltése"
+msgstr "Betöltendő blokk módosítók"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Lower Y limit of dungeons."
 msgstr "A tömlöcök alsó Y határa."
 
@@ -5166,17 +5390,16 @@ msgstr ""
 "látószögtől."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Makes all liquids opaque"
 msgstr "Az összes folyadékot átlátszatlanná teszi"
 
 #: src/settings_translation_file.cpp
 msgid "Map Compression Level for Disk Storage"
-msgstr ""
+msgstr "A térkép tömörítésének foka merevlemezen való tároláshoz"
 
 #: src/settings_translation_file.cpp
 msgid "Map Compression Level for Network Transfer"
-msgstr ""
+msgstr "A térkép tömörítésének foka hálózati átvitelhez"
 
 #: src/settings_translation_file.cpp
 msgid "Map directory"
@@ -5184,36 +5407,25 @@ msgstr "Térkép mappája"
 
 #: src/settings_translation_file.cpp
 msgid "Map generation attributes specific to Mapgen Carpathian."
-msgstr ""
+msgstr "A Kárpátok térképgenerátorra vonatkozó térképgenerálási beállítások."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen Flat.\n"
 "Occasional lakes and hills can be added to the flat world."
 msgstr ""
-"Térkép generálási jellemzők csak a Flat (lapos) térképgenerátor esetében.\n"
-"Esetenkénti tavak és dombok generálása a lapos világba.\n"
-"The default flags set in the engine are: none\n"
-"The flags string modifies the engine defaults.\n"
-"Flags that are not specified in the flag string are not modified from the "
-"default.\n"
-"Flags starting with \"no\" are used to explicitly disable them."
+"A Lapos térképgenerátor sajátos tulajdonságai.\n"
+"Alkalmanként tavak és dombok hozzáadódhatnak a lapos világhoz."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen Fractal.\n"
 "'terrain' enables the generation of non-fractal terrain:\n"
 "ocean, islands and underground."
 msgstr ""
-"Térkép generálási jellemzők csak a Flat (lapos) térképgenerátor esetében.\n"
-"Esetenkénti tavak és dombok generálása a lapos világba.\n"
-"The default flags set in the engine are: none\n"
-"The flags string modifies the engine defaults.\n"
-"Flags that are not specified in the flag string are not modified from the "
-"default.\n"
-"Flags starting with \"no\" are used to explicitly disable them."
+"A Fraktál térképgenerátor sajátos jellemzői.\n"
+"A 'terrain' engedélyezi a nem-fraktál terep generálását,\n"
+"mint az óceán, szigetek és a földalatti részek."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5224,43 +5436,42 @@ msgid ""
 "to become shallower and occasionally dry.\n"
 "'altitude_dry': Reduces humidity with altitude."
 msgstr ""
+"A Völgyek térképgenerátor sajátos jellemzői.\n"
+"'altitude_chill': csökkenti a hőmérsékletet a magassággal.\n"
+"'humid_rivers': megnöveli a páratartalmat a folyók körül.\n"
+"'vary_river_depth': ha engedélyezve van, az alacsony páratalom és a magas\n"
+"hőmérséklet hatására a folyók sekélyebbé válnak, és lehet, hogy "
+"kiszáradnak.\n"
+"'altitude_dry': csökkenti a páratartalmat a magassággal."
 
 #: src/settings_translation_file.cpp
 msgid "Map generation attributes specific to Mapgen v5."
-msgstr ""
+msgstr "A v5 térképgenerátor sajátos tulajdonságai."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen v6.\n"
 "The 'snowbiomes' flag enables the new 5 biome system.\n"
 "When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n"
 "the 'jungles' flag is ignored."
 msgstr ""
-"Térképgenerálási jellemzők csak a v6 térképgenerátor esetében.\n"
-"When snowbiomes are enabled jungles are enabled and the jungles flag is "
-"ignored.\n"
-"The default flags set in the engine are: biomeblend, mudflow\n"
-"The flags string modifies the engine defaults.\n"
-"Flags that are not specified in the flag string are not modified from the "
-"default.\n"
-"Flags starting with \"no\" are used to explicitly disable them."
+"A v6 térképgenerátor sajátos jellemzői.\n"
+"A 'snowbiomes' zászló engedélyezi az új 5 biomos rendszert.\n"
+"Amikor a 'snowbiomes' zászló engedélyezett a dzsungelek automatikusan "
+"engedélyezve vannak\n"
+"és a 'jungles' zászló figyelmen kívül van hagyva."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen v7.\n"
 "'ridges': Rivers.\n"
 "'floatlands': Floating land masses in the atmosphere.\n"
 "'caverns': Giant caves deep underground."
 msgstr ""
-"Térkép generálási jellemzők csak a Flat (lapos) térképgenerátor esetében.\n"
-"Esetenkénti tavak és dombok generálása a lapos világba.\n"
-"The default flags set in the engine are: none\n"
-"The flags string modifies the engine defaults.\n"
-"Flags that are not specified in the flag string are not modified from the "
-"default.\n"
-"Flags starting with \"no\" are used to explicitly disable them."
+"Térkép generálási jellemzők csak a v7 térképgenerátor esetében.\n"
+"'ridges': folyók.\n"
+"'floatlands': lebegő földtömegek a légkörben.\n"
+"'caverns': óriási barlangok mélyen a föld alatt."
 
 #: src/settings_translation_file.cpp
 msgid "Map generation limit"
@@ -5271,27 +5482,24 @@ msgid "Map save interval"
 msgstr "Térkép mentésének időköze"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Folyadékfrissítés tick"
+msgid "Map shadows update frames"
+msgstr "Árnyéktérkép frissítési idő"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
 msgstr "Térképblokk korlát"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapblock mesh generation delay"
-msgstr "Térkép generálási korlát"
+msgstr "Térképblokk háló generálási késleltetés"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapblock mesh generator's MapBlock cache size in MB"
-msgstr "Térkép generálási korlát"
+msgstr "Térképblokk hálógenerátor MapBlock gyorsítótár mérete MB-ban"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock unload timeout"
-msgstr ""
+msgstr "Térképblokk memóriaürítésének időkorlátja"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen Carpathian"
@@ -5371,48 +5579,51 @@ msgstr "Max folyadék feldolgozva lépésenként."
 
 #: src/settings_translation_file.cpp
 msgid "Max. clearobjects extra blocks"
-msgstr ""
+msgstr "Max. objektumtakarítás az extra blokkora"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Max. packets per iteration"
-msgstr "Max csomag ismétlésenként"
+msgstr "Maximum csomagok ismétlésenként"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum FPS"
 msgstr "Maximum FPS (képkocka/mp)"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum FPS when the window is not focused, or when the game is paused."
-msgstr "Maximum FPS a játék szüneteltetésekor."
+msgstr "Maximum FPS, amikor a játék szüneteltetve van, vagy nincs fókuszban."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Az árnyékok renderelésének maximális távolsága."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum forceloaded blocks"
-msgstr "A maximálisan terhelt blokkok"
+msgstr "Az erőltetett betöltésű blokkok maximuma"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum hotbar width"
-msgstr "Maximum hotbar szélesség"
+msgstr "Gyorselérési sáv maximális szélessége"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum limit of random number of large caves per mapchunk."
 msgstr ""
+"A véletlenszerűen egy térképdarabkára jutó nagy barlangok számának maximális "
+"korlátja."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum limit of random number of small caves per mapchunk."
 msgstr ""
+"A véletlenszerűen egy térképdarabkára jutó kis barlangok számának maximális "
+"korlátja."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum liquid resistance. Controls deceleration when entering liquid at\n"
 "high speed."
 msgstr ""
+"Maximális közegellenállás folyadékban. A nagy sebességgel folyadékba való\n"
+"belépéskor bekövetkező lassulást szabályozza."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5420,28 +5631,29 @@ msgid ""
 "The maximum total count is calculated dynamically:\n"
 "max_total = ceil((#clients + max_users) * per_client / 4)"
 msgstr ""
+"A szimultán küldött blokkok maximális száma kliensenként.\n"
+"A maximális összértéket így számoljuk dinamikusan:\n"
+"max_total = ceil((#clients + max_users) * per_client / 4)"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of blocks that can be queued for loading."
 msgstr "Maximum blokkok száma, amik sorban állhatnak betöltésre."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum number of blocks to be queued that are to be generated.\n"
 "This limit is enforced per player."
 msgstr ""
 "Maximum blokkok száma, amik sorban állhatnak generálásra.\n"
-"Hagyd üresen, hogy automatikusan legyen kiválasztva a megfelelő mennyiség."
+"Ez a korlát játékosonként van kényszerítve."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum number of blocks to be queued that are to be loaded from file.\n"
 "This limit is enforced per player."
 msgstr ""
 "Maximum blokkok száma, amik sorban állhatnak egy fájlból való betöltésre.\n"
-"Hagyd üresen, hogy automatikusan legyen kiválasztva a megfelelő mennyiség."
+"Ez a korlát játékosonként van kényszerítve."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5449,10 +5661,13 @@ msgid ""
 "be queued.\n"
 "This should be lower than curl_parallel_limit."
 msgstr ""
+"Az egyszerre folyó letöltések maximális száma. A korláton túli letöltéseket "
+"várólistára teszi.\n"
+"A curl_parallel_limit-nél kisebbnek kell lennie."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of forceloaded mapblocks."
-msgstr ""
+msgstr "Az erőltetetten betöltött térképblokkok maximális száma."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5468,50 +5683,51 @@ msgid ""
 "try reducing it, but don't reduce it to a number below double of targeted\n"
 "client number."
 msgstr ""
+"A lépésenként küldött csomagok maximális száma,\n"
+"ha lassú kapcsolattal rendelkezel, próbáld csökkenteni,\n"
+"de ne csökkentsd a kívánt kliensszám duplája alá."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum number of players that can be connected simultaneously."
 msgstr "Az egy időben csatlakozó játékosok maximális száma."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of recent chat messages to show"
-msgstr "A megjelenítendő csevegésüzenetek maximális száma."
+msgstr "A megjelenítendő csevegésüzenetek maximális száma"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of statically stored objects in a block."
 msgstr "Statikusan tárolt objektumok maximális száma egy térképblokkban."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum objects per block"
-msgstr "Maximum objektum térképblokkonként"
+msgstr "Maximum objektumok térképblokkonként"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum proportion of current window to be used for hotbar.\n"
 "Useful if there's something to be displayed right or left of hotbar."
 msgstr ""
-"Az aktuális ablak maximum hányada a hotbar számára.\n"
-"Hasznos, ha valamit el kell helyezni a hotbar jobb, vagy bal oldalán."
+"Az aktuális ablak maximum hányada a gyorselérési sáv számára.\n"
+"Hasznos, ha valamit el kell helyezni a sáv jobb, vagy bal oldalán."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum simultaneous block sends per client"
 msgstr "Az egyidejűleg a kliensenként küldött térképblokkok maximális száma"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum size of the out chat queue"
-msgstr ""
+msgstr "Kimenő üzenetek sorának maximális mérete"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum size of the out chat queue.\n"
 "0 to disable queueing and -1 to make the queue size unlimited."
 msgstr ""
+"A kimenő üzenetek sorának maximális mérete.\n"
+"0 letiltja a várolistára helyezést, míg -1 korlátlanná teszi a sor méretét."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
@@ -5524,6 +5740,8 @@ msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Az interaktív kérések (pl. szerverlista lekérése) számára rendelkezésre álló "
+"maximális idő milliszekundumban."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5535,7 +5753,7 @@ msgstr "Menük"
 
 #: src/settings_translation_file.cpp
 msgid "Mesh cache"
-msgstr ""
+msgstr "Poligonháló cashe"
 
 #: src/settings_translation_file.cpp
 msgid "Message of the day"
@@ -5551,7 +5769,7 @@ msgstr "Kijelölt objektum kiemelésére használt módszer."
 
 #: src/settings_translation_file.cpp
 msgid "Minimal level of logging to be written to chat."
-msgstr ""
+msgstr "A naplózás csevegésbe írásának minimális szintje."
 
 #: src/settings_translation_file.cpp
 msgid "Minimap"
@@ -5566,30 +5784,32 @@ msgid "Minimap scan height"
 msgstr "Kistérkép letapogatási magasság"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Minimum limit of random number of large caves per mapchunk."
-msgstr "3D-s zaj, amely meghatározza a tömlöcök számát egy mapchunkonként."
+msgstr ""
+"A véletlenszerűen egy térképdarabkára jutó nagy barlangok számának minimális "
+"korlátja."
 
 #: src/settings_translation_file.cpp
 msgid "Minimum limit of random number of small caves per mapchunk."
 msgstr ""
+"A véletlenszerűen egy térképdarabkára jutó kis barlangok számának minimális "
+"korlátja."
 
 #: src/settings_translation_file.cpp
 msgid "Minimum texture size"
 msgstr "Minimum textúra méret"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mipmapping"
-msgstr "Mip-mapping"
+msgstr "Mipmapping"
 
 #: src/settings_translation_file.cpp
 msgid "Mod channels"
 msgstr "Mod csatornák"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "A hudbar elemméretét módosítja"
+msgid "Modifies the size of the HUD elements."
+msgstr "A HUD elemméretét módosítja."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
@@ -5599,6 +5819,10 @@ msgstr "Monospace betűtípus útvonal"
 msgid "Monospace font size"
 msgstr "Monospace betűméret"
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr "Monospace betűméret osztója"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Hegy magasság zaj"
@@ -5632,6 +5856,8 @@ msgid ""
 "Multiplier for fall bobbing.\n"
 "For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
 msgstr ""
+"A zuhanás utáni fejbillenés szorzója.\n"
+"Például: 0 nincs biccentés; 1,0 normál; 2,0 dupla."
 
 #: src/settings_translation_file.cpp
 msgid "Mute key"
@@ -5648,6 +5874,10 @@ msgid ""
 "Current mapgens in a highly unstable state:\n"
 "-    The optional floatlands of v7 (disabled by default)."
 msgstr ""
+"Az új világ létrehozásakor használandó térképgenerátor neve.\n"
+"Új világ főmenüben történő létrehozása felülírja ezt.\n"
+"Jelenleg a következő térképgenerátorok nagyon instabilak:\n"
+"-    Az opcionális lebegő földek a v7-ben (alapértelmezés szerint tiltott)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5679,6 +5909,8 @@ msgid ""
 "Network port to listen (UDP).\n"
 "This value will be overridden when starting from the main menu."
 msgstr ""
+"Figyelt hálózati port (UDP).\n"
+"Főmenüből való indításkor felülíródik ez az érték."
 
 #: src/settings_translation_file.cpp
 msgid "New users need to input this password."
@@ -5686,7 +5918,7 @@ msgstr "Az új felhasználóknak ezt a jelszót kell megadniuk."
 
 #: src/settings_translation_file.cpp
 msgid "Noclip"
-msgstr ""
+msgstr "Noclip"
 
 #: src/settings_translation_file.cpp
 msgid "Noclip key"
@@ -5698,7 +5930,7 @@ msgstr "Node kiemelés"
 
 #: src/settings_translation_file.cpp
 msgid "NodeTimer interval"
-msgstr ""
+msgstr "NodeTimer időköz"
 
 #: src/settings_translation_file.cpp
 msgid "Noises"
@@ -5706,7 +5938,7 @@ msgstr "Zajok"
 
 #: src/settings_translation_file.cpp
 msgid "Number of emerge threads"
-msgstr ""
+msgstr "A térképblokk betöltő szálak száma"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5721,13 +5953,31 @@ msgid ""
 "processes, especially in singleplayer and/or when running Lua code in\n"
 "'on_generated'. For many users the optimum setting may be '1'."
 msgstr ""
+"A térképblokkok betöltésére használt szálak száma.\n"
+"Érték 0:\n"
+"-    Automatikus választás. A térképblokkok betöltését végző szálak száma\n"
+"-    \"processzorok száma - 2\" lesz, de legalább 1.\n"
+"Bármilyen más érték:\n"
+"-    Meghatározza a térképblokkbetöltő szálak számát, amelynek alsó korlátja "
+"1.\n"
+"FIGYELEM: A térképblokkbetöltő szálak számának növelése növeli a játékmotor "
+"mapgen\n"
+"folyamatainak sebességét, de csökkentheti a játékteljesítményt azáltal, hogy "
+"más\n"
+"folyamatokat akadályoznak, különösen egyjátékos módban és/vagy Lua kódok "
+"futtatásakor\n"
+"az 'on_generated' eseményben. Sok játékos számára valószínűleg az 1 az "
+"optimális beállítás."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
+"A /clearobjects parancs által egyidejűleg betölthető extra blokkok száma.\n"
+"Kompromisszum az SQLite tranzakciók erőforrásigénye és a\n"
+"memóriahasználat között (4096=100MB hüvelykujjszabályként)."
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
@@ -5741,6 +5991,8 @@ msgstr "Átlátszatlan folyadékok"
 msgid ""
 "Opaqueness (alpha) of the shadow behind the default font, between 0 and 255."
 msgstr ""
+"Az alapértelmezett betűtípus mögötti árnyék átlátszatlansága (alfa) 0 és 255 "
+"között."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5748,27 +6000,40 @@ msgid ""
 "formspec is\n"
 "open."
 msgstr ""
+"Megnyitja a szünet menüt, ha az ablak kikerül a fókuszból. Nem szünetel, ha "
+"nyitva van\n"
+"egy formspec panel."
+
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "A csevegésben lévő internetes linkek színének opcionális felülírása."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
+"A tartalék betűtípus elérési útvonala. TrueType betűtípusnak kell lenni.\n"
+"Bizonyos nyelvek ezt a betűtípust használják vagy ha az alapértelmezett "
+"betűtípus nem elérhető."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Path to save screenshots at. Can be an absolute or relative path.\n"
 "The folder will be created if it doesn't already exist."
 msgstr ""
+"A képernyőképek mentésének elérési útvonala. Lehet abszolút vagy relatív "
+"elérési út.\n"
+"Ha még nem létezik a mappa, létre lesz hozva."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Path to shader directory. If no path is defined, default location will be "
 "used."
 msgstr ""
+"Az árnyékolókat tartalmazó mappa elérési útvonala. Ha nincs beállítva, az "
+"alapértelmezett útvonalat használja."
 
 #: src/settings_translation_file.cpp
 msgid "Path to texture directory. All textures are first searched from here."
@@ -5776,31 +6041,34 @@ msgstr "Textúra mappa útvonala. Először minden textúrát itt keres a játé
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
+"Az alapértelmezett betűtípus elérési útja. TrueType betűtípusnak kell lenni."
+"\n"
+"Ha nem lehet betölteni a betűtípust, a tartalék betűtípust fogja használni."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
+"A monospace betűtípus elérési útvonala. TrueType betűtípusnak kell lenni.\n"
+"Ezt a betűtípust használja pl. a konzol és a profiler képernyő."
 
 #: src/settings_translation_file.cpp
 msgid "Pause on lost window focus"
-msgstr ""
+msgstr "Szüneteltetés ha az ablak kikerül a fókuszból"
 
 #: src/settings_translation_file.cpp
 msgid "Per-player limit of queued blocks load from disk"
 msgstr ""
+"A merevlemezről várólistára töltött blokkok számának korlátja játékosonként"
 
 #: src/settings_translation_file.cpp
 msgid "Per-player limit of queued blocks to generate"
 msgstr ""
+"A várólistára töltött létrehozandó blokkok számának korlátja játékosonként"
 
 #: src/settings_translation_file.cpp
 msgid "Physics"
@@ -5815,14 +6083,12 @@ msgid "Pitch move mode"
 msgstr "Pályamozgás mód"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Place key"
-msgstr "Repülés gomb"
+msgstr "Elhelyezés gomb"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Place repetition interval"
-msgstr "Jobb kattintás ismétlési időköz"
+msgstr "Elhelyezés ismétlési időköz"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5838,16 +6104,15 @@ msgstr "Játékos neve"
 
 #: src/settings_translation_file.cpp
 msgid "Player transfer distance"
-msgstr ""
+msgstr "Játékosátviteli távolság"
 
 #: src/settings_translation_file.cpp
 msgid "Player versus player"
 msgstr "Játékos játékos ellen"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Bilineáris szűrés"
+msgstr "Poisson szűrés"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5862,6 +6127,10 @@ msgid ""
 "Prevent digging and placing from repeating when holding the mouse buttons.\n"
 "Enable this when you dig or place too often by accident."
 msgstr ""
+"Ásás és lehelyezés ismétlődésének megakadályozása, amikor nyomva tartod az "
+"egérbombokat.\n"
+"Engedélyezd, ha túl gyakran fordul elő, hogy véletlenül lehelyezel vagy "
+"kiásol blokkokat."
 
 #: src/settings_translation_file.cpp
 msgid "Prevent mods from doing insecure things like running shell commands."
@@ -5892,19 +6161,24 @@ msgstr "Profiler váltó gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Profiling"
-msgstr ""
+msgstr "Pfolilozás"
 
 #: src/settings_translation_file.cpp
 msgid "Prometheus listener address"
-msgstr ""
+msgstr "Prometheus figyelési cím"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
+"Prometheus figyelési cím.\n"
+"Ha a Minetest-et az ENABLE_PROMETHEUS opció engedélyezésével állítták össze,"
+"\n"
+"elérhetővé válnak a Prometheus mérőszám figyelői ezen a címen.\n"
+"A mérőszámok itt érhetők el: http://127.0.0.1:30000/metrics"
 
 #: src/settings_translation_file.cpp
 msgid "Proportion of large caves that contain liquid."
@@ -5916,6 +6190,8 @@ msgid ""
 "Values larger than 26 will start to produce sharp cutoffs at cloud area "
 "corners."
 msgstr ""
+"A felhők kiterjedése 64 blokkos felhőnégyzetek számában mérve.\n"
+"26-nál nagyobb értékek éles határt eredményeznek a felhők sarkainál."
 
 #: src/settings_translation_file.cpp
 msgid "Raises terrain to make valleys around the rivers."
@@ -5934,9 +6210,8 @@ msgid "Recent Chat Messages"
 msgstr "Legutóbbi csevegésüzenetek"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Regular font path"
-msgstr "Betűtípus helye"
+msgstr "Betűtípus útvonala"
 
 #: src/settings_translation_file.cpp
 msgid "Remote media"
@@ -5953,7 +6228,7 @@ msgid ""
 msgstr ""
 "Színkódok eltávolítása a bejövő csevegésüzenetekből\n"
 "Használd ezt hogy megakadályozd, hogy a játékosok színeket használjanak az "
-"üzeneteikben."
+"üzeneteikben"
 
 #: src/settings_translation_file.cpp
 msgid "Replaces the default main menu with a custom one."
@@ -5976,22 +6251,32 @@ msgid ""
 "csm_restriction_noderange)\n"
 "READ_PLAYERINFO: 32 (disable get_player_names call client-side)"
 msgstr ""
+"Korlátozza bizonyos kliensoldali függvényekhez a hozzáférést a szerveren.\n"
+"Kombináld az alábbi bájtcímkéket a kliensoldali képességek korlátozásához,\n"
+"vagy állítsd 0-ra a korlátozások eltávolításához:\n"
+"LOAD_CLIENT_MODS: 1 (letitlja a kliensoldali modok betöltését)\n"
+"CHAT_MESSAGES: 2 (letiltja a send_chat_message hívásokat kliensoldalon)\n"
+"READ_ITEMDEFS: 4 (letiltja a get_item_def hívásokat kliensoldalon)\n"
+"READ_NODEDEFS: 8 (letiltja a get_node_def hívásokat kliensoldalon)\n"
+"LOOKUP_NODES_LIMIT: 16 (korlátozza a get_node hívásokat kliensoldalon a\n"
+"csm_restriction_noderange esetén)\n"
+"READ_PLAYERINFO: 32 (letiltja a get_player_names hívásokat kliensoldalon)"
 
 #: src/settings_translation_file.cpp
 msgid "Ridge mountain spread noise"
-msgstr ""
+msgstr "A hegyvonulatok kiterjedésének zaja"
 
 #: src/settings_translation_file.cpp
 msgid "Ridge noise"
-msgstr ""
+msgstr "Hegygerinc zaj"
 
 #: src/settings_translation_file.cpp
 msgid "Ridge underwater noise"
-msgstr ""
+msgstr "Víz alatti hegygerinc zaj"
 
 #: src/settings_translation_file.cpp
 msgid "Ridged mountain size noise"
-msgstr ""
+msgstr "Hegyvonulatok méretének zaja"
 
 #: src/settings_translation_file.cpp
 msgid "Right key"
@@ -6023,7 +6308,7 @@ msgstr "Folyóvölgy szélessége"
 
 #: src/settings_translation_file.cpp
 msgid "Rollback recording"
-msgstr ""
+msgstr "Visszavonási pontok rögzítése"
 
 #: src/settings_translation_file.cpp
 msgid "Rolling hill size noise"
@@ -6043,7 +6328,7 @@ msgstr "Biztonságos ásás és elhelyezés"
 
 #: src/settings_translation_file.cpp
 msgid "Sandy beaches occur when np_beach exceeds this value."
-msgstr ""
+msgstr "Homokos partok képződnek, ha az np_beach meghaladja ezt az értéket."
 
 #: src/settings_translation_file.cpp
 msgid "Save the map received by the client on disk."
@@ -6069,7 +6354,7 @@ msgstr ""
 "A legközelebbi-szomszéd-élsimítás szűrőt használja a GUI méretezésére.\n"
 "Ez elsimít néhány durva élt, és elhajlítja a pixeleket a méretezés "
 "csökkentésekor,\n"
-"de ennek az az ára, hogy elhomályosít néhány szélső pixelt, ha a képek nem\n"
+"de ennek az ára, hogy elhomályosít néhány szélső pixelt, ha a képek nem\n"
 "egész számok alapján vannak méretezve."
 
 #: src/settings_translation_file.cpp
@@ -6109,17 +6394,19 @@ msgstr "Folyómeder zaj"
 #: src/settings_translation_file.cpp
 msgid "Second of 4 2D noises that together define hill/mountain range height."
 msgstr ""
+"A második a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/"
+"hegységek magasságát."
 
 #: src/settings_translation_file.cpp
 msgid "Second of two 3D noises that together define tunnels."
 msgstr ""
+"A második a két 3D zajból, amelyek együttesen meghatározzák az alagutakat."
 
 #: src/settings_translation_file.cpp
 msgid "Security"
 msgstr "Biztonság"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
 msgstr "Lásd: http://www.sqlite.org/pragma.html#pragma_synchronous"
 
@@ -6136,7 +6423,6 @@ msgid "Selection box width"
 msgstr "Kijelölő doboz szélessége"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Selects one of 18 fractal types.\n"
 "1 = 4D \"Roundy\" Mandelbrot set.\n"
@@ -6204,7 +6490,7 @@ msgstr "Szerver port"
 
 #: src/settings_translation_file.cpp
 msgid "Server side occlusion culling"
-msgstr ""
+msgstr "Takarásban lévő térképblokkok szerveroldali kiválogatása"
 
 #: src/settings_translation_file.cpp
 msgid "Serverlist URL"
@@ -6231,36 +6517,35 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Az árnyékok kivehetőségét szabályozza.\n"
+"Kisebb érték világosabb, magasabb érték sötétebb árnyékokat jelent."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Az árnyékok lágy szélének kiterjedését szabályozza.\n"
+"Kisebb érték élesebb, nagyobb érték lágyabb árnyékokat jelent.\n"
+"Minimális érték: 1,0; maximális érték: 10,0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"A Nap/Hold pályájának fokokban mért döntési szögét szabályozza.\n"
+"A 0 érték azt jelenti, hogy nincs döntés / függőleges a pályájuk.\n"
+"Minimális érték: 0,0; maximális érték: 60,0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"A \"true\" beállítás engedélyezi a levelek hullámzását.\n"
+"Állítsa igazra az árnyáktérképezés (Shadow Mapping) engedélyezéséhez.\n"
 "Az árnyalók engedélyezése szükséges hozzá."
 
 #: src/settings_translation_file.cpp
@@ -6293,6 +6578,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Az árnyék textúrájának minőségét 32 bitesre állítja.\n"
+"Ha hamis, 16 bites textúrát fog használni.\n"
+"Ez sokkal több grafikai hibát okoz az árnyékon."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6305,27 +6593,26 @@ msgid ""
 "cards.\n"
 "This only works with the OpenGL video backend."
 msgstr ""
-"Az árnyalók fejlett vizuális effekteket engedélyeznek és növelhetik a "
-"teljesítményt néhány videókártya esetében.\n"
+"Az árnyalók fejlett vizuális effekteket tesznek lehetővé és növelhetik a "
+"teljesítményt\n"
+"néhány videókártya esetében.\n"
 "Csak OpenGL-el működnek."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Képernyőkép minőség"
+msgstr "Árnyék szűrő minőség"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Az árnyéktérkép maximális renderelési távolsága blokkban"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "32 bites árnyéktérkép textúra"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Minimum textúra méret"
+msgstr "Árnyéktérkép textúra méret"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6335,7 +6622,7 @@ msgstr "Betűtípus árnyékának eltolása. Ha 0, akkor nem lesz árnyék rajzo
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Árnyék kivehetősége"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6352,18 +6639,16 @@ msgid "Show entity selection boxes"
 msgstr "Entitások kijelölő dobozának megjelenítése"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Show entity selection boxes\n"
 "A restart is required after changing this."
 msgstr ""
-"Nyelv beállítása. Hagyd üresen a rendszer nyelvének használatához.\n"
+"Entitás hitboxok megjelenítése.\n"
 "A változtatás után a játék újraindítása szükséges."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Show nametag backgrounds by default"
-msgstr "Félkövér betűtípus alapértelmezetten"
+msgid "Show name tag backgrounds by default"
+msgstr "Névcímkék háttere alapértelmezésben látszik"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6378,6 +6663,14 @@ msgid ""
 "Altering this value is for special usage, leaving it unchanged is\n"
 "recommended."
 msgstr ""
+"A mapgen által generált térképdarabka mérete térképblokkokban (16 blokk) "
+"mérve.\n"
+"FIGYELEM!: Nincs értelme és bizonyos veszélyekkel is jár ennek az értéknek\n"
+"5 fölés emelése.\n"
+"Ha csökkentjük ezt az értéket, gyakrabban fordulnak elő barlangok és "
+"tömlöcök.\n"
+"Változtasd meg, ha valami különleges okból kell, de ajánlott\n"
+"változatlanul hagyni."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6385,14 +6678,18 @@ msgid ""
 "increase the cache hit %, reducing the data being copied from the main\n"
 "thread, thus reducing jitter."
 msgstr ""
+"A poligonhálót generáló MapBlock cache mérete. Növelése megnöveli a\n"
+"cache kiszolgálási teljesítményét, ezáltal csökken a fő szálból másolt "
+"adatok\n"
+"mennyisége, és ezáltal csökken a szaggatás."
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Égitestek pályájának döntése"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
-msgstr ""
+msgstr "W szelet"
 
 #: src/settings_translation_file.cpp
 msgid "Slope and fill work together to modify the heights."
@@ -6409,23 +6706,26 @@ msgstr "Kis barlangok minimális száma"
 #: src/settings_translation_file.cpp
 msgid "Small-scale humidity variation for blending biomes on borders."
 msgstr ""
+"A biomok közötti átmeneti határra vonatkozó kisléptékű páratartalom-"
+"ingadozás."
 
 #: src/settings_translation_file.cpp
 msgid "Small-scale temperature variation for blending biomes on borders."
 msgstr ""
+"A biomok közötti átmeneti határra vonatkozó kisléptékű hőmérséklet-ingadozás."
 
 #: src/settings_translation_file.cpp
 msgid "Smooth lighting"
 msgstr "Simított megvilágítás"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Smooths camera when looking around. Also called look or mouse smoothing.\n"
 "Useful for recording videos."
 msgstr ""
-"Kamera mozgásának simítása mozgáskor és körbenézéskor.\n"
-"Videófelvételekhez hasznos."
+"Kamera mozgásának simítása körbenézéskor. Körbenézés és egérsimításnak is "
+"hívják.\n"
+"Hasznos videók felvételénél."
 
 #: src/settings_translation_file.cpp
 msgid "Smooths rotation of camera in cinematic mode. 0 to disable."
@@ -6445,12 +6745,11 @@ msgstr "Lopakodás sebessége"
 
 #: src/settings_translation_file.cpp
 msgid "Sneaking speed, in nodes per second."
-msgstr "Lopakodás sebessége node/másodpercben"
+msgstr "Lopakodás sebessége node/másodpercben."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Betűtípus árnyék átlátszósága"
+msgstr "Lágy árnyék sugara"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6463,6 +6762,13 @@ msgid ""
 "(obviously, remote_media should end with a slash).\n"
 "Files that are not present will be fetched the usual way."
 msgstr ""
+"Meghatározza, mely URL-ről töltse le a kliens a médiatartalmat az UDP "
+"helyett.\n"
+"$filename -nek elérhetőnek kell lennie a $remote_media$filename helyről "
+"cURL\n"
+"használatával (nyilván, a remote_media elérési útnak perjelre kell végződni)."
+"\n"
+"A nem elérhető fájlokat a normál módon fogja letölteni."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6470,6 +6776,21 @@ msgid ""
 "Note that mods or games may explicitly set a stack for certain (or all) "
 "items."
 msgstr ""
+"A blokkok, tárgyak és eszközök alapértelmezett kötegméretét szabályozza.\n"
+"Megjegyzendő, hogy a modok vagy játékok kifejezetten meghatározhatják a "
+"kötegek méretét bizonyos vagy az összes tárgy esetén."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Az árnyéktérkép firssítését széthúzza a megadott számú képkockára.\n"
+"Magasabb érték esetén az árnyékok késhetnek, alacsabb érékek\n"
+"viszont több erőforrást igényelnek.\n"
+"Minimális érték: 1; maximális érték: 16"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6477,6 +6798,9 @@ msgid ""
 "Controls the width of the range to be boosted.\n"
 "Standard deviation of the light curve boost Gaussian."
 msgstr ""
+"A fénygörbe kiemelésének hatósugara.\n"
+"A kiemelendő tartomány szélességét szabályozza.\n"
+"A fénygörbe kiemelés Gauss-görbéjének szórása."
 
 #: src/settings_translation_file.cpp
 msgid "Static spawnpoint"
@@ -6487,18 +6811,16 @@ msgid "Steepness noise"
 msgstr "Meredekség zaj"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Step mountain size noise"
-msgstr "Terep magasság"
+msgstr "Lépcsős hegyek méretének zajossága"
 
 #: src/settings_translation_file.cpp
 msgid "Step mountain spread noise"
-msgstr ""
+msgstr "Lépcsős hegy kiterjedésének zaja"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Strength of 3D mode parallax."
-msgstr "Generált normálfelületek erőssége."
+msgstr "3D mód parallax hatásának erőssége."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6506,14 +6828,17 @@ msgid ""
 "The 3 'boost' parameters define a range of the light\n"
 "curve that is boosted in brightness."
 msgstr ""
+"A fénygörbe kiemelésének erőssége.\n"
+"A 3 'boost' parameter a fénygörbe egy tartományát\n"
+"határozza meg, amelyeken erősebbek a fények."
 
 #: src/settings_translation_file.cpp
 msgid "Strict protocol checking"
-msgstr ""
+msgstr "Szigorú protokollellenőrzés"
 
 #: src/settings_translation_file.cpp
 msgid "Strip color codes"
-msgstr ""
+msgstr "Színkódok kinyerése"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6528,10 +6853,27 @@ msgid ""
 "server-intensive extreme water flow and to avoid vast flooding of the\n"
 "world surface below."
 msgstr ""
+"Az egybefüggő lebegő föld rétegre opcionálisan helyezhető vízfelület szintje."
+"\n"
+"Alapértelmezésben a víz nem engedélyezett és csak akkor helyezi le, ha ez "
+"az\n"
+"érték nagyobb, mint 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (a "
+"vékonyítás\n"
+"felső részének kezdete).\n"
+"***FIGYELEM! VESZÉLYES LEHET A VILÁGOKRA ÉS A SZERVERTELJESÍTMÉNYRE***:\n"
+"Ha endgedélyezve van a vízelhelyezés, úgy kell konfigurálni a lebegő "
+"földeket és\n"
+"tesztelni kell, hogy valóban egybefüggő réteget alkosson, az "
+"'mgv7_floatland_density'\n"
+"értékének 2,0-nak (vagy az 'mgv7_np_floatland'-től függően más szükséges "
+"értéknek)\n"
+"kell lenni, hogy elkerülhető legyen a szervert leterhelő extrém vízfolyás és "
+"az alatta lévő\n"
+"földfelszín elárasztása."
 
 #: src/settings_translation_file.cpp
 msgid "Synchronous SQLite"
-msgstr ""
+msgstr "Szinkron SQLite"
 
 #: src/settings_translation_file.cpp
 msgid "Temperature variation for biomes."
@@ -6546,7 +6888,6 @@ msgid "Terrain base noise"
 msgstr "Terep alapzaj"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Terrain height"
 msgstr "Terep magasság"
 
@@ -6564,6 +6905,9 @@ msgid ""
 "Controls proportion of world area covered by hills.\n"
 "Adjust towards 0.0 for a larger proportion."
 msgstr ""
+"A dombok terep zajküszöbe.\n"
+"A világ dombokkal fedett területének arányát szabályozza.\n"
+"Állítsd 0,0-hoz közelebb, hogy az arány növekedjen."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6571,10 +6915,13 @@ msgid ""
 "Controls proportion of world area covered by lakes.\n"
 "Adjust towards 0.0 for a larger proportion."
 msgstr ""
+"A tavak terep zajküszöbe.\n"
+"A világ tavakkal fedett területének arányát szabályozza.\n"
+"Állítsd 0,0-hoz közelebb, hogy az arány növekedjen."
 
 #: src/settings_translation_file.cpp
 msgid "Terrain persistence noise"
-msgstr ""
+msgstr "Terep folytonossági zaj"
 
 #: src/settings_translation_file.cpp
 msgid "Texture path"
@@ -6584,8 +6931,12 @@ msgstr "Textúrák útvonala"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Az árnyéktérkép rendereléséhez használt textúraméret.\n"
+"Kettő hatványának kell lennie.\n"
+"Nagyobb számok nagyobb árnyékokat hoznak létre, de ez egyben "
+"erőforrásigényesebb is."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6596,30 +6947,42 @@ msgid ""
 "this option allows enforcing it for certain node types. Note though that\n"
 "that is considered EXPERIMENTAL and may not work properly."
 msgstr ""
+"Egy blokk textúráját lehet a blokkhoz vagy a világhoz igazítani.\n"
+"Az első megoldás jobban illik olyan dolgokhoz, mint a gépek, bútorok stb.,\n"
+"míg a másodikkal jobban beleillenek a környezetükbe a lépcsők és "
+"mikroblokkok.\n"
+"Mivel azonban ez a lehetőség még új, és így a régebbi szerverek még nem "
+"használják,\n"
+"ezzel az opcióval ki lehet kényszeríteni ezt bizonyos blokkokra. Meg kell "
+"azonban\n"
+"jegyezni, hogy ez még KÍSÉRLETI fázisban van és lehet, hogy nem működik "
+"helyesen."
 
 #: src/settings_translation_file.cpp
 msgid "The URL for the content repository"
 msgstr "Az URL a tartalomtárhoz"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "The deadzone of the joystick"
-msgstr "A használni kívánt joystick azonosítója"
+msgid "The dead zone of the joystick"
+msgstr "A joystick holttere"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "The default format in which profiles are being saved,\n"
 "when calling `/profiler save [format]` without format."
 msgstr ""
+"A profilok mentéséhez használt alapértelmezett formátum, amikor\n"
+"formátum nélkül kerül meghívásra a `/profiler save [format]` parancs."
 
 #: src/settings_translation_file.cpp
 msgid "The depth of dirt or other biome filler node."
-msgstr ""
+msgstr "A föld vagy egyéb biom feltöltő blokk mélysége."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "The file path relative to your worldpath in which profiles will be saved to."
 msgstr ""
+"A profilok mentésének relatív elérési útja a világod elérési útjához képest."
 
 #: src/settings_translation_file.cpp
 msgid "The identifier of the joystick to use"
@@ -6628,6 +6991,7 @@ msgstr "A használni kívánt joystick azonosítója"
 #: src/settings_translation_file.cpp
 msgid "The length in pixels it takes for touch screen interaction to start."
 msgstr ""
+"Az érintőképernyős interakció megkezdéséhez szükséges távolság pixelekben."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6637,10 +7001,15 @@ msgid ""
 "Default is 1.0 (1/2 node).\n"
 "Requires waving liquids to be enabled."
 msgstr ""
+"A hullámzó folyadékok felszínének maximális magassága.\n"
+"4,0 = A hullámok magasága két blokk.\n"
+"0,0 = A hullámok egyáltalán nem mozognak.\n"
+"Az alapértelmezett érték 1,0 (1/2 blokk).\n"
+"A hullámzó folyadék engedélyezése szükséges hozzá."
 
 #: src/settings_translation_file.cpp
 msgid "The network interface that the server listens on."
-msgstr ""
+msgstr "A hálózati interfész, amelyen a szerver figyel."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6661,6 +7030,13 @@ msgid ""
 "maintained.\n"
 "This should be configured together with active_object_send_range_blocks."
 msgstr ""
+"A játékosok körüli blokktérfogat sugara, amelyen belül érvényesülnek\n"
+"az aktív blokkok dolgai. Térképblokkban (16 blokk) mérve.\n"
+"Az aktív blokkokban betöltődnek az objektumok és ABM-ek futnak.\n"
+"Ez egyben az a legkisebb sugár is, amelyen belül az aktív objektumokról "
+"(mobok) gondoskodik a játék.\n"
+"Ezt a beállítást az active_object_send_range_blocks-szal összhangban kell "
+"megadni."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6671,12 +7047,21 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
+"A renderelő háttérprogram.\n"
+"Ha ezt megváltoztatod, újraindítás szükséges.\n"
+"Megjegyzés: Androidon, hagyd OGLES1-en, ha bizonytalan vagy! Lehet, hogy nem "
+"indul az app különben.\n"
+"Más platformokon az OpenGL az ajánlott.\n"
+"Az árnyékolókat az OpenGL (csak asztali rendszeren) és OGLES2 (kísérleti) "
+"támogatja"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
+"A jostick tengelyeinek érzékenysége, amely\n"
+"a játékbeli látómező mozgatását befolyásolja."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6685,6 +7070,12 @@ msgid ""
 "setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n"
 "set to the nearest valid value."
 msgstr ""
+"A körülvett, illetve takarásban lévő blokkok árnyékolásának erőssége "
+"(sötétsége).\n"
+"Alacsonyabb érték sötétebb, magasabb érték világosabb. E beállítás érvényes\n"
+"értéktartománya 0,25-től 4,0-ig terjed. Ha a tartományon kívüli értéket "
+"adunk meg,\n"
+"a legközelebbi érvényes értékre lesz állítva."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6692,29 +7083,33 @@ msgid ""
 "capacity until an attempt is made to decrease its size by dumping old queue\n"
 "items.  A value of 0 disables the functionality."
 msgstr ""
+"A másodpercben megadott idő, ameddig a folyadékok várólistája a számítási\n"
+"teljesítmény fölé nőhet, és ezután megpróbálja csökkenteni a méretét azáltal,"
+"\n"
+"hogy törli a régóta sorbanálló elemeket.  A 0 érték letiltja ezt a funkciót."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "The time budget allowed for ABMs to execute on each step\n"
 "(as a fraction of the ABM Interval)"
 msgstr ""
+"Az ABM-ek rendelkezésére álló lépésenkénti végrehajtási időkeret\n"
+"(az ABM intervallum törtrésze)"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The time in seconds it takes between repeated events\n"
 "when holding down a joystick button combination."
 msgstr ""
-"Ennyi másodperc szükséges az ismételt jobb kattintáshoz a jobb egérgomb "
-"nyomva tartásakor."
+"Ennyi másodperc szükséges az esemény megismétléséhez\n"
+"a joystick gombok nyomva tartásakor."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The time in seconds it takes between repeated node placements when holding\n"
 "the place button."
 msgstr ""
-"Ennyi másodperc szükséges az ismételt jobb kattintáshoz a jobb egérgomb "
+"Ennyi másodperc szükséges az ismételt node elhelyezéshez az elhelyezés gomb\n"
 "nyomva tartásakor."
 
 #: src/settings_translation_file.cpp
@@ -6727,26 +7122,33 @@ msgid ""
 "enabled. Also the vertical distance over which humidity drops by 10 if\n"
 "'altitude_dry' is enabled."
 msgstr ""
+"Az a függőleges távolság, amely során a hőmérséklet 20 fokkal csökken, ha az "
+"'altitude_chill'\n"
+"be van kapcsolva. Ugyanez a távolság, amely során a páratartalom esik 10 "
+"egységgel, ha az\n"
+"'altitude_dry' be van kapcsolva."
 
 #: src/settings_translation_file.cpp
 msgid "Third of 4 2D noises that together define hill/mountain range height."
 msgstr ""
+"A harmadik a négy 2D zajból, amelyek együttesen meghatározzák a dombságok/"
+"hegységek magasságát."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Time in seconds for item entity (dropped items) to live.\n"
 "Setting it to -1 disables the feature."
 msgstr ""
-"Annak az ideje, hogy mennyi ideig \"élnek\" az eldobott tárgyak.\n"
+"Annak az ideje, hogy mennyi ideig maradnak meg az eldobott tárgyak.\n"
 "-1-re állítás kikapcsolja ezt a funkciót."
 
 #: src/settings_translation_file.cpp
 msgid "Time of day when a new world is started, in millihours (0-23999)."
-msgstr ""
+msgstr "Az új világ létrehozásakor érvényes napszak milliórában (0-23999)."
 
 #: src/settings_translation_file.cpp
 msgid "Time send interval"
-msgstr ""
+msgstr "Idő küldési gyakoriság"
 
 #: src/settings_translation_file.cpp
 msgid "Time speed"
@@ -6755,6 +7157,8 @@ msgstr "Idő sebessége"
 #: src/settings_translation_file.cpp
 msgid "Timeout for client to remove unused map data from memory."
 msgstr ""
+"A kliens rendelkezésére álló időkorlát, hogy eltávolítsa a használaton "
+"kívüli térképadatokat a memóriából."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6780,6 +7184,10 @@ msgstr "Eszköztipp késleltetés"
 msgid "Touch screen threshold"
 msgstr "Érintőképernyő küszöbe"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "Teljesítménybeli kompromisszumok"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Fa zaj"
@@ -6789,7 +7197,6 @@ msgid "Trilinear filtering"
 msgstr "Trilineáris szűrés"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "True = 256\n"
 "False = 128\n"
@@ -6808,9 +7215,8 @@ msgid "URL to the server list displayed in the Multiplayer Tab."
 msgstr "A Többjátékos fül alatt megjelenített szerverlista URL-je."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Undersampling"
-msgstr "Renderelés:"
+msgstr "Alulmintavételezés"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6820,24 +7226,28 @@ msgid ""
 "image.\n"
 "Higher values result in a less detailed image."
 msgstr ""
+"Az alulmintavételezés olyan, mintha kisebb képernyőfelbontást használnál, "
+"de\n"
+"csak a játék világára van hatással, a GUI-t változatlanul hagyja.\n"
+"Sokkal jobb teljesítmény érhető el vele annak árán, hogy a kép kevésbé\n"
+"részletgazdaggá válik. Magasabb értékek kevésbé részletes képet "
+"eredményeznek."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Unlimited player transfer distance"
 msgstr "Korlátlan játékosátviteli távolság"
 
 #: src/settings_translation_file.cpp
 msgid "Unload unused server data"
-msgstr ""
+msgstr "A használaton kívüli szerveradatok eltávolítása a memóriából"
 
 #: src/settings_translation_file.cpp
 msgid "Upper Y limit of dungeons."
 msgstr "A tömlöcök felső Y határa."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Upper Y limit of floatlands."
-msgstr "A tömlöcök felső Y határa."
+msgstr "A lebegő földek felső Y határa."
 
 #: src/settings_translation_file.cpp
 msgid "Use 3D cloud look instead of flat."
@@ -6857,10 +7267,13 @@ msgstr "Bilineáris szűrés a textúrák méretezésekor."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
+"Mipmapping használata a textúrák méretezéséhez. Kis mértékben növelheti a\n"
+"teljesítményt, különösen nagy felbontású textúracsomagok használatakor.\n"
+"Gamma-megőrző zsugorítás nem támogatott."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6872,6 +7285,13 @@ msgid ""
 "If set to 0, MSAA is disabled.\n"
 "A restart is required after changing this option."
 msgstr ""
+"Többmintás élsimítás (MSAA) használata a blokkélek simításához.\n"
+"Ez az algoritmus kisimítja a 3D látómezőt miközben a kép éles marad,\n"
+"a textúrák beljsejét azonban nem módosítja\n"
+"(ami főleg az átlátszó textúráknál vehető észre).\n"
+"A blokkok között látható rések jelennek meg, ha az árnyékolók nincsenek\n"
+"engedélyezve. Ha 0-ra van állítva, az MSAA tiltva van.\n"
+"E beállítás megváltoztatása után újraindítás szükséges."
 
 #: src/settings_translation_file.cpp
 msgid "Use trilinear filtering when scaling textures."
@@ -6879,14 +7299,13 @@ msgstr "Trilineáris szűrés a textúrák méretezéséhez."
 
 #: src/settings_translation_file.cpp
 msgid "VBO"
-msgstr ""
+msgstr "VBO"
 
 #: src/settings_translation_file.cpp
 msgid "VSync"
 msgstr "Függőleges szinkron"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Valley depth"
 msgstr "Völgyek mélysége"
 
@@ -6895,12 +7314,10 @@ msgid "Valley fill"
 msgstr "Völgyek kitöltése"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Valley profile"
-msgstr "Völgyek meredeksége"
+msgstr "Völgyek profilja"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Valley slope"
 msgstr "Völgyek meredeksége"
 
@@ -6910,7 +7327,7 @@ msgstr "A biom töltőanyag mélységének változékonysága."
 
 #: src/settings_translation_file.cpp
 msgid "Variation of maximum mountain height (in nodes)."
-msgstr ""
+msgstr "A legnagyobb eltérés a hegyek magasságában (blokkokban)."
 
 #: src/settings_translation_file.cpp
 msgid "Variation of number of caves."
@@ -6921,20 +7338,24 @@ msgid ""
 "Variation of terrain vertical scale.\n"
 "When noise is < -0.55 terrain is near-flat."
 msgstr ""
+"A terep függőleges kiterjedésének mozgástere.\n"
+"Ha a zaj < -0,55, akkor a terep szinte lapos."
 
 #: src/settings_translation_file.cpp
 msgid "Varies depth of biome surface nodes."
-msgstr ""
+msgstr "A biomok felületét képező blokkréteg mélységét variálja."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Varies roughness of terrain.\n"
 "Defines the 'persistence' value for terrain_base and terrain_alt noises."
 msgstr ""
+"A terep töredezettségét variálja.\n"
+"Meghatározza a terrain_base és terrain_alt zajok folytonosságának értékét."
 
 #: src/settings_translation_file.cpp
 msgid "Varies steepness of cliffs."
-msgstr "A szirtek meredekségét állítja."
+msgstr "A szirtek meredekségét variálja."
 
 #: src/settings_translation_file.cpp
 msgid "Vertical climbing speed, in nodes per second."
@@ -6950,7 +7371,7 @@ msgstr "Videó driver"
 
 #: src/settings_translation_file.cpp
 msgid "View bobbing factor"
-msgstr ""
+msgstr "Fejbillegési faktor"
 
 #: src/settings_translation_file.cpp
 msgid "View distance in nodes."
@@ -6974,20 +7395,19 @@ msgstr "Látóterület"
 
 #: src/settings_translation_file.cpp
 msgid "Virtual joystick triggers Aux1 button"
-msgstr ""
+msgstr "Virtuális joystick gombok Aux1 gomb"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
 msgstr "Hangerő"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Volume of all sounds.\n"
 "Requires the sound system to be enabled."
 msgstr ""
-"Parallax occlusion mapping bekapcsolása.\n"
-"A shaderek engedélyezve kell legyenek."
+"Az összes hang hangereje.\n"
+"A hangrendszer engedélyezésére van szükség hozzá."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6997,6 +7417,11 @@ msgid ""
 "Has no effect on 3D fractals.\n"
 "Range roughly -2 to 2."
 msgstr ""
+"A 4D fraktál generált 3D szeletének W koordinátája.\n"
+"Meghatározza, hogy a 4D-s alakzat mely 3D-s szeletét kell generálni.\n"
+"Megváltoztatja a fraktál alakját.\n"
+"Nincs hatása a 3D fraktálokra.\n"
+"Nagyjából -2 és 2 közötti az értéktartománya."
 
 #: src/settings_translation_file.cpp
 msgid "Walking and flying speed, in nodes per second."
@@ -7046,12 +7471,19 @@ msgstr "Hullámzó folyadékok hullámhossza"
 msgid "Waving plants"
 msgstr "Hullámzó növények"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Internetes hivatkozások színe"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
 "filtered in software, but some images are generated directly\n"
 "to hardware (e.g. render-to-texture for nodes in inventory)."
 msgstr ""
+"Ha a gui_scaling_filter értéke igaz, minden GUI képet szoftveres\n"
+"szűrő fogja kezelni, de néhány kép közvetlenül a harverre\n"
+"generálódik (pl. a felszerelésben lévő blokkok textúrára renderelése)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7060,6 +7492,10 @@ msgid ""
 "to the old scaling method, for video drivers that don't\n"
 "properly support downloading textures back from hardware."
 msgstr ""
+"Ha a gui_scaling_filter_txr2img be van kapcsolva, ezeket a képeket\n"
+"a hardverről a szoftverbe másolja méretezésre.  Ha ki van kapcsolva,\n"
+"a régi méretezési módszert használja, azoknál a videó drivereknél,\n"
+"amelyek nem megfelelően támogatják a textúra hardverről való letöltését."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7067,37 +7503,46 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Használatban vannak-e freetype betűtípusok. Szükséges a beépített freetype "
-"támogatás."
+"A bilineáris/trilineáris/anizotróp szűrők használatakor, a kis felbontású "
+"textúrák\n"
+"homályosak lehetnek, ezért automatikusan felskálázza őket legközelebbi\n"
+"szomszéd módszerrel, hogy megőrizze az éles pixeleket. Ez a beállítás "
+"meghatározza\n"
+"a minimális textúraméretet a felnagyított textúrákhoz; magasabb értéknél "
+"élesebb,\n"
+"de több memóriát igényel. 2 hatványait ajánlott használni. CSAK akkor "
+"érvényes ez a\n"
+"beállítás, ha a bilineáris/trilineáris/anizotróp szűrés engedélyezett.\n"
+"Ez egyben azon blokkok alap textúraméreteként is használatos, amelyeknél a "
+"világhoz\n"
+"igazítva kell méretezni a textúrát."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
+"Látszódjon-e a névcímkék háttere alapértelmezésként.\n"
+"A modok ettől még a beállíthatják a hátteret."
 
 #: src/settings_translation_file.cpp
 msgid "Whether node texture animations should be desynchronized per mapblock."
 msgstr ""
+"Legyen-e független a blokkok textúraanimációinak időzítése az egyes "
+"térképblokkokban."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Whether players are shown to clients without any range limit.\n"
 "Deprecated, use the setting player_transfer_distance instead."
 msgstr ""
+"Lássák-e a játékosokat a kliensek mindenféle távolsági korlát nélkül.\n"
+"Elavult, használd a player_transfer_distance beállítást ehelyett."
 
 #: src/settings_translation_file.cpp
 msgid "Whether to allow players to damage and kill each other."
@@ -7122,6 +7567,10 @@ msgid ""
 "In-game, you can toggle the mute state with the mute key or by using the\n"
 "pause menu."
 msgstr ""
+"Némítsuk-e le a hangokat. Bármikor visszakapcsolhatod a hangokat, kivéve,\n"
+"ha a hangrendszer le van tiltva (enable_sound=false).\n"
+"A játékon belül a némítás állapotát a némítás gombbal vagy a szünet\n"
+"menüben tudod beállítani."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7130,9 +7579,9 @@ msgstr ""
 "A hibakereső információ megjelenítése (ugyanaz a hatás, ha F5-öt nyomunk)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Kezdeti ablak szélessége."
+msgstr ""
+"A kezdőablak szélessége. Teljes képernyős módban nem kerül figyelmbe vételre."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7157,7 +7606,6 @@ msgstr ""
 "Ez nem szükséges, ha a főmenüből indítják."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "World start time"
 msgstr "Világ-kezdőidő"
 
@@ -7170,10 +7618,18 @@ msgid ""
 "See also texture_min_size.\n"
 "Warning: This option is EXPERIMENTAL!"
 msgstr ""
+"A világhoz igazított textúrák több blokkra is ki kiterjedhetnek. A szerver\n"
+"azonban nem biztos, hogy az általad kívánt módon terjeszti ki azt, különösen,"
+"\n"
+"ha egyedi tervezésű textúracsomagról van szó; ezzel a beállítással a kliens\n"
+"megpróbálja automatikusan meghatározni a méretezést a textúra mérete alapján."
+"\n"
+"Lásd még texture_min_size.\n"
+"Figyelem: Ez KÍSÉRLETI beállítás!"
 
 #: src/settings_translation_file.cpp
 msgid "World-aligned textures mode"
-msgstr ""
+msgstr "Világhoz igazított textúrakezelési mód"
 
 #: src/settings_translation_file.cpp
 msgid "Y of flat ground."
@@ -7184,6 +7640,8 @@ msgid ""
 "Y of mountain density gradient zero level. Used to shift mountains "
 "vertically."
 msgstr ""
+"A hegyek sűrűséggradiensének alapsíkjának Y koordinátája. A hegyek "
+"függőleges eltolásához használatos."
 
 #: src/settings_translation_file.cpp
 msgid "Y of upper limit of large caves."
@@ -7200,6 +7658,12 @@ msgid ""
 "For a solid floatland layer, this controls the height of hills/mountains.\n"
 "Must be less than or equal to half the distance between the Y limits."
 msgstr ""
+"Az az Y irányú távolság, amely során a lebegő földek a maximális sűrűségtől "
+"kezdve teljesen elvékonyodnak.\n"
+"A vékonyítás ennél az Y határtól való távolságnál kezdőik.\n"
+"Egybefüggő lebegő föld rétegek esetén, ez a beállítás szabályozza a dombok/"
+"hegyek magasságát.\n"
+"Kisebbnek vagy egyenlőnek kell lennie az Y határok közötti távolság felénél."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of average terrain surface."
@@ -7221,37 +7685,24 @@ msgstr "Alacsony terep és tengerfenék Y szintje."
 msgid "Y-level of seabed."
 msgstr "Tengerfenék Y szintje."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL fájlletöltés időkorlát"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL időkorlát"
+msgstr "cURL interaktív időtúllépés"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "cURL párhuzamossági korlát"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kreatív mód: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Sérülés: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7400,6 +7851,9 @@ msgstr "cURL párhuzamossági korlát"
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "Betűtípus árnyék alfa (átlátszatlanság, 0 és 255 között)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType betűtípusok"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Teljes képernyő BPP"
 
@@ -7418,6 +7872,9 @@ msgstr "cURL párhuzamossági korlát"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 támogatás."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Fájl telepítése: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "Nagy barlang mélység"
@@ -7514,6 +7971,9 @@ msgstr "cURL párhuzamossági korlát"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Ezt a betűtípust bizonyos nyelvek használják."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Az árnyalók engedélyezéséhez OpenGL driver használata szükséges."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Váltás „mozi” módba"
 
@@ -7526,8 +7986,21 @@ msgstr "cURL párhuzamossági korlát"
 #~ msgid "Waving water"
 #~ msgstr "Hullámzó víz"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Használhatók-e FreeType betűtípusok. Szükséges a beépített FreeType "
+#~ "támogatás.\n"
+#~ "Ha ki van kapcsolva, bittérképes és XML vektoros betűtípusok lesznek "
+#~ "használva helyette."
+
 #~ msgid "Yes"
 #~ msgstr "Igen"
 
+#~ msgid "You died."
+#~ msgstr "Meghaltál."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 27a1019a001fcb0cbdfcaaad64f587756eff39fc..82f1da18f8c0a291238b2c8e70f346f6f85df386 100644 (file)
@@ -2,9 +2,10 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Indonesian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-02-23 15:50+0000\n"
-"Last-Translator: Reza Almanda <rezaalmanda27@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-10 23:53+0000\n"
+"Last-Translator: Muhammad Rifqi Priyo Susanto "
+"<muhammadrifqipriyosusanto@gmail.com>\n"
 "Language-Team: Indonesian <https://hosted.weblate.org/projects/minetest/"
 "minetest/id/>\n"
 "Language: id\n"
@@ -12,49 +13,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.5\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Ukuran maksimum antrean obrolan keluar"
+msgstr "Bersihkan antrean obrolan keluar"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Perintah obrolan"
+msgstr "Perintah kosong."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Menu Utama"
+msgstr "Kembali ke menu utama"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Perintah lokal"
+msgstr "Perintah tidak sah "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Perintah yang dikeluarkan: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Pemain tunggal"
+msgstr "Daftar pemain daring"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Pemain tunggal"
+msgstr "Pemain daring: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Antran obrolan keluar sudah dibersihkan."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Perintah ini dinonaktifkan oleh server."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +59,41 @@ msgstr "Bangkit kembali"
 msgid "You died"
 msgstr "Anda mati"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Anda mati"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Perintah lokal"
+msgstr "Perintah yang ada:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Perintah lokal"
+msgstr "Perintah yang ada: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Perintah tidak tersedia: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Dapatkan bantuan untuk perintah-perintah"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Pakai '.help <cmd>' untuk mendapatkan informasi lanjut atau '.help all' "
+"untuk menampilkan semuanya."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[semua | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "Oke"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<tiada yang tersedia>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Suatu galat terjadi pada suatu skrip Lua:"
@@ -302,6 +296,10 @@ msgstr "Pasang $1"
 msgid "Install missing dependencies"
 msgstr "Pasang dependensi yang belum ada"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Pemasangan: Tipe berkas tidak didukung atau arsip rusak"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -631,8 +629,8 @@ msgid "Offset"
 msgstr "Pergeseran"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
-msgstr "Persistensi"
+msgid "Persistence"
+msgstr "Kegigihan"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid integer."
@@ -743,14 +741,6 @@ msgstr ""
 "Pemasangan mod: Tidak dapat mencari nama folder yang sesuai untuk paket mod "
 "$1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Pemasangan: Tipe berkas \"$1\" tidak didukung atau arsip rusak"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Pemasangan: berkas: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Tidak dapat mencari mod atau paket mod yang sah"
@@ -776,9 +766,8 @@ msgid "Loading..."
 msgstr "Memuat..."
 
 #: builtin/mainmenu/serverlistmgr.lua
-#, fuzzy
 msgid "Public server list is disabled"
-msgstr "Skrip sisi klien dimatikan"
+msgstr "Daftar server publik dimatikan"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
@@ -787,16 +776,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Tentang"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Penyumbang Aktif"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Batas pengiriman objek aktif"
+msgstr "Penggambar aktif:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -931,9 +919,8 @@ msgid "Start Game"
 msgstr "Mulai Permainan"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Alamat: "
+msgstr "Alamat"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -949,22 +936,20 @@ msgstr "Mode kreatif"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Kerusakan"
+msgstr "Kerusakan/PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Hapus favorit"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "Favorit"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Server Tidak Kompatibel"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -975,18 +960,16 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Umumkan Server"
+msgstr "Server Publik"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Segarkan"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Keterangan server"
+msgstr "Keterangan Server"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1029,13 +1012,12 @@ msgid "Connected Glass"
 msgstr "Kaca Tersambung"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Bayangan fon"
+msgstr "Bayangan dinamis"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Bayangan dinamis: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1043,15 +1025,15 @@ msgstr "Daun Megah"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Tinggi"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Rendah"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Menengah"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1079,7 +1061,7 @@ msgstr "Garis Bentuk Nodus"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "None"
-msgstr "Tidak ada"
+msgstr "Tidak Ada"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Leaves"
@@ -1125,10 +1107,6 @@ msgstr "Pencahayaan Halus"
 msgid "Texturing:"
 msgstr "Peneksturan:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Untuk menggunakan shader, pengandar OpenGL harus digunakan."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Pemetaan Nada"
@@ -1143,11 +1121,11 @@ msgstr "Filter Trilinear"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Ultratinggi"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Sangat Rendah"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1161,7 +1139,7 @@ msgstr "Air Berombak"
 msgid "Waving Plants"
 msgstr "Tanaman Berayun"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Sambungan kehabisan waktu."
 
@@ -1190,8 +1168,8 @@ msgid "Connection error (timed out?)"
 msgstr "Galat sambungan (terlalu lama?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Tidak dapat mencari atau memuat permainan \""
+msgid "Could not find or load game"
+msgstr "Tidak dapat mencari atau memuat permainan"
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1233,14 +1211,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Alamat: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Mode Kreatif: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Kerusakan: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Mode: "
@@ -1262,6 +1232,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Nama Server: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Sebuah galat serialisasi terjadi:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Akses ditolak. Alasan: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Maju otomatis dimatikan"
@@ -1270,6 +1249,22 @@ msgstr "Maju otomatis dimatikan"
 msgid "Automatic forward enabled"
 msgstr "Maju otomatis dinyalakan"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Batasan blok disembunyikan"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Batasan blok ditampilkan untuk semua blok"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Batasan blok ditampilkan untuk blok saat ini"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Batasan blok ditampilkan untuk blok sekitar"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Pembaruan kamera dimatikan"
@@ -1278,9 +1273,13 @@ msgstr "Pembaruan kamera dimatikan"
 msgid "Camera update enabled"
 msgstr "Pembaruan kamera dinyalakan"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Tidak bisa menampilkan batasan blok (butuh hak 'basic_debug')"
+
 #: src/client/game.cpp
 msgid "Change Password"
-msgstr "Ganti kata sandi"
+msgstr "Ganti Kata Sandi"
 
 #: src/client/game.cpp
 msgid "Cinematic mode disabled"
@@ -1290,6 +1289,10 @@ msgstr "Mode sinema dimatikan"
 msgid "Cinematic mode enabled"
 msgstr "Mode sinema dinyalakan"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Klien terputus"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Skrip sisi klien dimatikan"
@@ -1298,6 +1301,10 @@ msgstr "Skrip sisi klien dimatikan"
 msgid "Connecting to server..."
 msgstr "Menyambung ke server..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Sambungan gagal karena sebab yang tak diketahui"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Lanjutkan"
@@ -1335,6 +1342,11 @@ msgstr ""
 "- Roda tetikus: pilih barang\n"
 "- %s: obrolan\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Tidak bisa menyelesaikan alamat: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Membuat klien..."
@@ -1464,9 +1476,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Peta mini sedang dilarang oleh permainan atau mod"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Pemain tunggal"
+msgstr "Multipemain"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1540,6 +1551,21 @@ msgstr "Sistem suara tidak didukung dalam buatan ini"
 msgid "Sound unmuted"
 msgstr "Suara dibunyikan"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Server ini mungkin menjalankan versi %s yang berbeda."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Tidak bisa menyambung ke %s karena IPv6 dimatikan"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Tidak bisa mendengarkan %s karena IPv6 dimatikan"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1631,7 +1657,7 @@ msgstr "Execute"
 
 #: src/client/keycode.cpp
 msgid "Help"
-msgstr "Help"
+msgstr "Bantuan"
 
 #: src/client/keycode.cpp
 msgid "Home"
@@ -1874,6 +1900,14 @@ msgstr "Peta mini mode permukaan, perbesaran %dx"
 msgid "Minimap in texture mode"
 msgstr "Peta mini mode tekstur"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Gagal membuka laman web"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Membuka laman web"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Kata sandi tidak cocok!"
@@ -1902,9 +1936,8 @@ msgid "Proceed"
 msgstr "Lanjut"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Spesial\" = turun"
+msgstr "\"Aux1\" = turun"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1916,7 +1949,7 @@ msgstr "Lompat otomatis"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1924,7 +1957,7 @@ msgstr "Mundur"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Batasan blok"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2077,8 +2110,9 @@ msgid "Muted"
 msgstr "Dibisukan"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Volume Suara: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Volume Suara: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2102,14 +2136,13 @@ msgstr ""
 "Jika dimatikan, joystick virtual akan menengah di posisi sentuhan pertama."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Gunakan joystick virtual untuk mengetuk tombol \"aux\".\n"
-"Jika dinyalakan, joystick virtual juga akan mengetuk tombol \"aux\" saat "
+"(Android) Gunakan joystick virtual untuk mengetuk tombol \"Aux1\".\n"
+"Jika dinyalakan, joystick virtual juga akan mengetuk tombol \"Aux1\" saat "
 "berada di luar lingkaran utama."
 
 #: src/settings_translation_file.cpp
@@ -2330,6 +2363,12 @@ msgstr ""
 "Atur konfigurasi dpi ke layar Anda (selain X11/Android saja) misalnya untuk "
 "layar 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Menyesuaikan kepadatan tampilan yang dideteksi, dipakai untuk mengatur skala "
+"elemen UI."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2463,14 +2502,12 @@ msgid "Autoscaling mode"
 msgstr "Mode penyekalaan otomatis"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Tombol lompat"
+msgstr "Tombol Aux1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Tombol spesial untuk memanjat/turun"
+msgstr "Tombol Aux1 untuk memanjat/turun"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2621,9 +2658,12 @@ msgstr ""
 "Nilai 0.0 adalah minimum, 1.0 adalah maksimum."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Ambang batas jumlah pesan sebelum ditendang keluar"
+msgstr "Ambang batas waktu pesan perintah obrolan"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Perintah obrolan"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2658,8 +2698,8 @@ msgid "Chat toggle key"
 msgstr "Tombol beralih obrolan"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Perintah obrolan"
+msgid "Chat weblinks"
+msgstr "Tautan web obrolan"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2677,6 +2717,14 @@ msgstr "Tombol mode sinema"
 msgid "Clean transparent textures"
 msgstr "Bersihkan tekstur transparan"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Tautan web yang bisa diklik (klik-tengah atau Ctrl+klik-kiri) dibolehkan "
+"dalam konsol obrolan."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klien"
@@ -2722,9 +2770,8 @@ msgid "Colored fog"
 msgstr "Kabut berwarna"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Kabut berwarna"
+msgstr "Bayangan berwarna"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2767,6 +2814,30 @@ msgstr ""
 msgid "Command key"
 msgstr "Tombol perintah"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Tingkat kompresi saat menyimpan blok peta ke diska.\n"
+"-1 - tingkat kompresi bawaan\n"
+"0 - kompresi sedikit, tercepat\n"
+"9 - kompresi terbaik, terlambat"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Tingkat kompresi saat mengirimkan blok peta kepada klien.\n"
+"-1 - tingkat kompresi bawaan\n"
+"0 - kompresi sedikit, tercepat\n"
+"9 - kompresi terbaik, terlambat"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Sambungkan kaca"
@@ -2867,10 +2938,10 @@ msgstr "Keburaman crosshair"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Keburaman crosshair (keopakan, dari 0 sampai 255).\n"
-"Juga mengatur warna crosshair objek"
+"Juga mengatur warna crosshair objek."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2950,10 +3021,13 @@ msgstr "Ukuran tumpukan bawaan"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Mengatur kualitas filter bayangan.\n"
+"Ini menyimulasikan efek bayangan halus dengan menerapkan PCF atau\n"
+"diska Poisson, tetapi menggunakan sumber daya lebih banyak."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3078,6 +3152,10 @@ msgstr "Matikan anticurang"
 msgid "Disallow empty passwords"
 msgstr "Larang kata sandi kosong"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Faktor Skala Kepadatan Tampilan"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Nama domain dari server yang akan ditampilkan pada daftar server."
@@ -3128,18 +3206,31 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Menyalakan filter diska Poisson.\n"
+"Nilai true berarti memakai diska Poisson untuk \"bayangan halus\". Nilai "
+"lain berarti\n"
+"memakai filter PCF."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Menyalakan bayangan berwarna.\n"
+"Nilai true berarti nodus agak tembus pandang memiliki bayangan berwarna.\n"
+"Ini sangat membutuhkan sumber daya besar."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
 msgstr "Gunakan jendela konsol"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable creative mode for all players"
-msgstr "Gunakan mode kreatif pada peta baru."
+msgstr "Nyalakan mode kreatif untuk semua pemain"
 
 #: src/settings_translation_file.cpp
 msgid "Enable joysticks"
@@ -3157,13 +3248,6 @@ msgstr "Nyalakan pengamanan mod"
 msgid "Enable players getting damage and dying."
 msgstr "Membolehkan pemain terkena kerusakan dan mati."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Gunakan masukan pengguna acak (hanya digunakan untuk pengujian)."
@@ -3274,6 +3358,12 @@ msgstr ""
 "akan tidak berfungsi.\n"
 "Perubahan pengaturan ini membutuhkan mulai ulang."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Jarak pencetakan data profiling mesin"
@@ -3335,12 +3425,11 @@ msgid "Fast movement"
 msgstr "Gerak cepat"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Gerak cepat (lewat tombol \"spesial\").\n"
+"Gerak cepat (lewat tombol \"Aux1\").\n"
 "Membutuhkan hak \"fast\" pada server."
 
 #: src/settings_translation_file.cpp
@@ -3373,7 +3462,6 @@ msgid "Filmic tone mapping"
 msgstr "Pemetaan suasana filmis"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3383,7 +3471,9 @@ msgstr ""
 "Tekstur yang difilter dapat memadukan nilai RGB dengan tetangganya yang\n"
 "sepenuhnya transparan, yang biasanya diabaikan oleh pengoptimal PNG,\n"
 "terkadang menghasilkan tepi gelap atau terang pada tekstur transparan. \n"
-"Terapkan filter ini untuk membersihkannya ketika memuat tekstur."
+"Terapkan filter ini untuk membersihkannya ketika memuat tekstur. Ini "
+"dinyalakan\n"
+"otomatis jika mipmap dinyalakan."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3474,11 +3564,17 @@ msgid "Font size"
 msgstr "Ukuran fon"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Ukuran fon bawaan dalam poin (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Ukuran fon monospace bawaan dalam poin (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3489,6 +3585,17 @@ msgstr ""
 "Ukuran fon teks obrolan terkini dan prompt obrolan dalam poin (pt).\n"
 "Nilai 0 akan memakai ukuran bawaan."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3550,10 +3657,6 @@ msgstr "Jenis fraktal"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Bagian dari jarak pandang tempat kabut mulai tampak"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Fon FreeType"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3610,7 +3713,7 @@ msgstr "Callback global"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Atribut pembuatan peta global.\n"
 "Dalam pembuat peta v6, flag \"decorations\" mengatur semua hiasan, kecuali\n"
@@ -3697,10 +3800,9 @@ msgid "Heat noise"
 msgstr "Noise panas"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Tinggi ukuran jendela mula-mula."
+msgstr "Tinggi ukuran jendela mula-mula. Ini diabaikan dalam mode layar penuh."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3954,12 +4056,11 @@ msgstr ""
 "dengan jeda agar tidak membuang tenaga CPU dengan percuma."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Jika dimatikan, tombol \"spesial\" digunakan untuk terbang cepat jika mode\n"
+"Jika dimatikan, tombol \"Aux1\" digunakan untuk terbang cepat jika mode\n"
 "terbang dan cepat dinyalakan."
 
 #: src/settings_translation_file.cpp
@@ -3986,14 +4087,12 @@ msgstr ""
 "Hal ini membutuhkan hak \"noclip\" pada server."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Jika dinyalakan, tombol \"spesial\" digunakan untuk bergerak turun alih-"
-"alih\n"
+"Jika dinyalakan, tombol \"Aux1\" digunakan untuk bergerak turun alih-alih\n"
 "tombol \"menyelinap\"."
 
 #: src/settings_translation_file.cpp
@@ -4055,6 +4154,8 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Jika pelaksanaan perintah obrolan lebih lama daripada ini (dalam detik),\n"
+"tambahkan informasi waktu ke pesan perintah obrolan"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4112,8 +4213,8 @@ msgstr ""
 "Ini biasanya hanya dibutuhkan oleh kontributor inti/bawaan"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
-msgstr "Melengkapi perintah obrolan saat didaftarkan, dengan perkakas."
+msgid "Instrument chat commands on registration."
+msgstr "Perkakas perintah obrolan saat pendaftaran."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4206,7 +4307,7 @@ msgid "Joystick button repetition interval"
 msgstr "Jarak penekanan tombol joystick terus-menerus"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Zona mati joystick"
 
 #: src/settings_translation_file.cpp
@@ -5319,9 +5420,8 @@ msgid "Map save interval"
 msgstr "Selang waktu menyimpan peta"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Detikan pembaruan cairan"
+msgid "Map shadows update frames"
+msgstr "Bingkai pembaruan peta bayangan"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5435,7 +5535,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Jarak maksimum untuk menggambar bayangan."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5565,18 +5665,19 @@ msgstr ""
 "0 untuk mematikan pengantrean dan -1 untuk mengatur antrean tanpa batas."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Waktu maksimum dalam milidetik saat mengunduh berkas (misal.: mengunduh mod)."
+"Waktu maksimum saat mengunduh berkas (misal.: mengunduh mod) dalam milidetik."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Waktu maksimum permintaan interaktif (misal ambil daftar server), dalam "
+"milidetik."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5639,8 +5740,8 @@ msgid "Mod channels"
 msgstr "Saluran mod"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "Mengubah ukuran dari elemen hudbar."
+msgid "Modifies the size of the HUD elements."
+msgstr "Mengubah ukuran elemen HUD."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
@@ -5650,6 +5751,11 @@ msgstr "Jalur fon monospace"
 msgid "Monospace font size"
 msgstr "Ukuran fon monospace"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Ukuran fon monospace"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Noise ketinggian gunung"
@@ -5794,12 +5900,12 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Jumlah dari blok tambahan yang dapat dimuat oleh /clearobjects dalam satu "
 "waktu.\n"
-"Ini adalah pemilihan antara transaksi sqlite dan\n"
+"Ini adalah pemilihan antara transaksi SQLite dan\n"
 "penggunaan memori (4096=100MB, kasarannya)."
 
 #: src/settings_translation_file.cpp
@@ -5826,10 +5932,13 @@ msgstr ""
 "dibuka."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Penimpaan opsional untuk warna tautan web pada obrolan."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5858,10 +5967,9 @@ msgid "Path to texture directory. All textures are first searched from here."
 msgstr "Jalur ke direktori tekstur. Semua tekstur akan dicari mulai dari sini."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Jalur ke fon bawaan.\n"
@@ -5870,10 +5978,9 @@ msgstr ""
 "Fon cadangan akan dipakai jika fon tidak dapat dimuat."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Jalur ke fon monospace.\n"
@@ -5934,9 +6041,8 @@ msgid "Player versus player"
 msgstr "Pemain lawan pemain"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Pemfilteran bilinear"
+msgstr "Pemfilteran Poisson"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5991,9 +6097,9 @@ msgstr "Alamat pendengar Prometheus"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Alamat pendengar Prometheus.\n"
 "Jika Minetest dikompilasi dengan pilihan ENABLE_PROMETHEUS dinyalakan,\n"
@@ -6334,36 +6440,36 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Atur kekuatan bayangan.\n"
+"Nilai rendah berarti bayangan lebih terang, nilai tinggi berarti lebih gelap."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Atur besar jari-jari bayangan halus.\n"
+"Nilai rendah berarti bayangan lebih tajam, nilai tinggi berarti lebih "
+"halus.\n"
+"Nilai minimum: 1.0; nilai maksimum 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Atur kemiringan orbit Matahari/Bulan dalam derajat.\n"
+"Nilai 0 berarti tidak miring/orbit tegak.\n"
+"Nilai minimum: 0.0; nilai maksimum 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Atur ke true untuk menyalakan daun melambai.\n"
+"Atur ke true untuk menyalakan Pemetaan Bayangan.\n"
 "Membutuhkan penggunaan shader."
 
 #: src/settings_translation_file.cpp
@@ -6396,6 +6502,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Atur kualitas tekstur bayangan ke 32 bit.\n"
+"Nilai false berarti tekstur 16 bit akan dipakai.\n"
+"Ini akan menimbulkan lebih banyak artefak pada bayangan."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6414,22 +6523,20 @@ msgstr ""
 "Ini hanya bekerja dengan video OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Kualitas tangkapan layar"
+msgstr "Kualitas filter bayangan"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Jarak maks. peta bayangan (dalam nodus) untuk digambar"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Tekstur peta bayangan dalam 32 bit"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Ukuran tekstur minimum"
+msgstr "Ukuran tekstur peta bayangan"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6441,7 +6548,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Kekuatan bayangan"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6464,9 +6571,8 @@ msgstr ""
 "Dibutuhkan mulai ulang setelah mengganti ini."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Show nametag backgrounds by default"
-msgstr "Fon tebal bawaan"
+msgid "Show name tag backgrounds by default"
+msgstr "Tampilkan latar belakang tanda nama secara bawaan"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6501,7 +6607,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Kemiringan Orbit Benda Langit"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6562,9 +6668,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Kelajuan menyelinap dalam nodus per detik."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Keburaman bayangan fon"
+msgstr "Jari-jari bayangan halus"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6592,6 +6697,18 @@ msgstr ""
 "Catat bahwa mod dan permainan dapat mengatur tumpukan untuk sebagian (atau "
 "semua) barang."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Menyebarkan pembaruan peta bayangan dalam jumlah bingkai yang diberikan.\n"
+"Nilai tinggi bisa membuat bayangan patah-patah, nilai rendah akan butuh\n"
+"sumber daya lebih banyak.\n"
+"Nilai minimum: 1; nilai maksimum: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6724,8 +6841,11 @@ msgstr "Jalur tekstur"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Ukuran tekstur tempat peta bayangan digambar.\n"
+"Ini harus bernilai perpangkatan dua.\n"
+"Nilai yang besar akan menghasilkan bayangan yang bagus, tetapi lebih berat."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6748,7 +6868,7 @@ msgid "The URL for the content repository"
 msgstr "URL dari gudang konten"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "Zona mati joystick yang digunakan"
 
 #: src/settings_translation_file.cpp
@@ -6823,7 +6943,6 @@ msgstr ""
 "Ini harus diatur bersama dengan active_object_range."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6841,7 +6960,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Kepekaan dari sumbu joystick untuk menggerakkan batas\n"
 "tampilan dalam permainan."
@@ -6961,6 +7080,10 @@ msgstr "Jeda tooltip"
 msgid "Touch screen threshold"
 msgstr "Ambang batas layar sentuh"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Noise pepohonan"
@@ -7039,13 +7162,13 @@ msgstr "Gunakan pemfilteran bilinear saat mengubah ukuran tekstur."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
-"Pakai mip mapping untuk penyekalaan tekstur. Bisa sedikit menaikkan\n"
+"Pakai mipmap untuk penyekalaan tekstur. Bisa sedikit menaikkan\n"
 "kinerja, terutama pada saat memakai paket tekstur beresolusi tinggi.\n"
-"Pengecilan dengan tepat gamma tidak didukung."
+"Pengecilan dengan tepat-gamma tidak didukung."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7166,9 +7289,8 @@ msgid "Viewing range"
 msgstr "Jarak pandang"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Joystick virtual mengetuk tombol aux"
+msgstr "Joystick virtual mengetuk tombol Aux1"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7246,6 +7368,10 @@ msgstr "Panjang ombak air"
 msgid "Waving plants"
 msgstr "Tanaman berayun"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Warna tautan web"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7269,13 +7395,12 @@ msgstr ""
 "mendukung pengunduhan tekstur dari perangkat keras."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7284,27 +7409,19 @@ msgstr ""
 "rendah dapat dikaburkan sehingga diperbesar otomatis dengan interpolasi\n"
 "nearest-neighbor untuk menjaga ketajaman piksel. Ini mengatur ukuran\n"
 "tekstur minimum untuk tekstur yang diperbesar; semakin tinggi semakin\n"
-"tajam, tetapi butuh memori lebih. Perpangkatan dua disarankan. Mengatur\n"
-"ini menjadi lebih dari 1 mungkin tidak tampak perubahannya kecuali\n"
-"menggunakan filter bilinear/trilinear/anisotropik.\n"
+"tajam, tetapi butuh memori lebih. Perpangkatan dua disarankan. Pengaturan\n"
+"ini HANYA diterapkan jika menggunakan filter bilinear/trilinear/"
+"anisotropik.\n"
 "Ini juga dipakai sebagai ukuran dasar tekstur nodus untuk penyekalaan\n"
 "otomatis tekstur yang sejajar dengan dunia."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Apakah fon FreeType digunakan, membutuhkan dukungan FreeType saat "
-"dikompilasi.\n"
-"Jika dimatikan, fon bitmap dan vektor XML akan dipakai."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
+"Apakah latar belakang tanda nama ditampilkan secara bawaan.\n"
+"Mod masih bisa mengatur latar belakang."
 
 #: src/settings_translation_file.cpp
 msgid "Whether node texture animations should be desynchronized per mapblock."
@@ -7352,9 +7469,8 @@ msgid ""
 msgstr "Apakah menampilkan informasi awakutu klien (sama dengan menekan F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Lebar ukuran jendela mula-mula."
+msgstr "Lebar ukuran jendela mula-mula. Ini diabaikan dalam mode layar penuh."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7454,40 +7570,11 @@ msgstr "Ketinggian Y dari medan yang lebih rendah dan dasar laut."
 msgid "Y-level of seabed."
 msgstr "Ketinggian Y dari dasar laut."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Tingkat kompresi ZLib saat pengiriman blok peta kepada klien.\n"
-"-1 - tingkat kompresi Zlib bawaan\n"
-"0 - tanpa kompresi, tercepat\n"
-"9 - kompresi terbaik, terlambat\n"
-"(tingkat 1-3 pakai metode \"cepat\" Zlib, 4-9 pakai metode normal)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Tingkat kompresi ZLib saat penyimpanan blok peta kepada klien.\n"
-"-1 - tingkat kompresi Zlib bawaan\n"
-"0 - tanpa kompresi, tercepat\n"
-"9 - kompresi terbaik, terlambat\n"
-"(tingkat 1-3 pakai metode \"cepat\" Zlib, 4-9 pakai metode normal)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Batas waktu cURL mengunduh berkas"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
 msgstr "Waktu habis untuk cURL"
 
@@ -7495,6 +7582,12 @@ msgstr "Waktu habis untuk cURL"
 msgid "cURL parallel limit"
 msgstr "Batas cURL paralel"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Mode Kreatif: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Kerusakan: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7665,6 +7758,9 @@ msgstr "Batas cURL paralel"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Ukuran fon cadangan bawaan dalam poin (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Fon FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP layar penuh"
 
@@ -7683,6 +7779,9 @@ msgstr "Batas cURL paralel"
 #~ msgid "IPv6 support."
 #~ msgstr "Dukungan IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Pemasangan: berkas: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Kedalaman lava"
 
@@ -7813,6 +7912,9 @@ msgstr "Batas cURL paralel"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Fon ini akan digunakan pada bahasa tertentu."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Untuk menggunakan shader, pengandar OpenGL harus digunakan."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Mode sinema"
 
@@ -7836,6 +7938,15 @@ msgstr "Batas cURL paralel"
 #~ msgid "Waving water"
 #~ msgstr "Air berombak"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Apakah fon FreeType digunakan, membutuhkan dukungan FreeType saat "
+#~ "dikompilasi.\n"
+#~ "Jika dimatikan, fon bitmap dan vektor XML akan dipakai."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Apakah dungeon terkadang muncul dari medan."
 
@@ -7851,5 +7962,9 @@ msgstr "Batas cURL paralel"
 #~ msgid "Yes"
 #~ msgstr "Ya"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Anda mati"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index b4930bf850c1eba4821ad3553abde96af6b74696..0a0997f38a10f247b45307fb42bb57f135f177a1 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Italian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-03-25 17:29+0000\n"
-"Last-Translator: Alessandro Mandelli <mandelli.alessandro@ngi.it>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-12-02 01:31+0000\n"
+"Last-Translator: Simone Starace <simone.starace93@gmail.com>\n"
 "Language-Team: Italian <https://hosted.weblate.org/projects/minetest/"
 "minetest/it/>\n"
 "Language: it\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.10-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Dimensione massima della coda esterna della chat"
+msgstr "Pulisci la coda esterna della chat"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Comandi della chat"
+msgstr "Comando vuoto."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Torna al menu"
+msgstr "Ritorna al menu principale"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Comando locale"
+msgstr "Comando Invalido: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Comando rilasciato: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Gioco locale"
+msgstr "Lista di giocatori online"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Gioco locale"
+msgstr "Giocatori Online: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "La coda esterna della chat è vuota adesso."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Questo comando è stato disabilitato dal server."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,33 +58,28 @@ msgstr "Rinasci"
 msgid "You died"
 msgstr "Sei morto"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Sei morto"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Comando locale"
+msgstr "Comandi disponibili:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Comando locale"
+msgstr "Comandi disponibili: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Comando non disponibile: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Ottieni aiuto per i comandi"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Scrivi '.help <cmd>' per avere più informazioni, oppure '.help all' per "
+"avere la lista completa."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
@@ -100,6 +89,10 @@ msgstr ""
 msgid "OK"
 msgstr "Ok"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<nessuno disponibile>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Si è verificato un errore in uno script Lua:"
@@ -302,6 +295,10 @@ msgstr "Installa $1"
 msgid "Install missing dependencies"
 msgstr "Installa le dipendenze mancanti"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Installazione: Tipo di file non supportato o archivio danneggiato"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -632,7 +629,7 @@ msgid "Offset"
 msgstr "Scarto"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Persistenza"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -744,14 +741,6 @@ msgstr ""
 "Installa mod: Impossibile trovare un nome cartella corretto per il pacchetto "
 "mod $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Installa: Tipo di file non supportato \"$1\" o archivio danneggiato"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Install: File: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Impossibile trovare un mod o un pacchetto mod validi"
@@ -788,16 +777,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Riguardo a"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Contributori attivi"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Raggio di invio degli oggetti attivi"
+msgstr "Rendering Attivo:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -932,9 +920,8 @@ msgid "Start Game"
 msgstr "Gioca"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Indirizzo: "
+msgstr "Indirizzo"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -959,13 +946,12 @@ msgid "Del. Favorite"
 msgstr "Elimina preferito"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Preferito"
+msgstr "Preferiti"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Server Incompatibili"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -976,16 +962,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Annunciare il server"
+msgstr "Server Pubblici"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Ricarica"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Descrizione del server"
 
@@ -1030,13 +1014,12 @@ msgid "Connected Glass"
 msgstr "Vetro contiguo"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Ombreggiatura carattere"
+msgstr "Ombre dinamiche"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Ombre dinamiche: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1044,15 +1027,15 @@ msgstr "Foglie di qualità"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Basso"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Medio"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1126,10 +1109,6 @@ msgstr "Luce uniforme"
 msgid "Texturing:"
 msgstr "Resa immagini:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Per abilitare gli shader si deve usare il driver OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tone Mapping"
@@ -1144,11 +1123,11 @@ msgstr "Filtro trilineare"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Molto Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Molto Basso"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1162,7 +1141,7 @@ msgstr "Liquidi ondeggianti"
 msgid "Waving Plants"
 msgstr "Piante ondeggianti"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Connessione scaduta."
 
@@ -1191,8 +1170,8 @@ msgid "Connection error (timed out?)"
 msgstr "Errore di connessione (scaduta?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Impossibile trovare o caricare il gioco \""
+msgid "Could not find or load game"
+msgstr "Impossibile trovare o caricare il gioco \" "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1234,14 +1213,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Indirizzo: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Modalità creativa: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Ferimento: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Modalità: "
@@ -1263,6 +1234,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Nome server: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Un errore di serializzazione si è verificato:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Accesso negato. Motivo: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Avanzamento automatico disabilitato"
@@ -1271,6 +1251,22 @@ msgstr "Avanzamento automatico disabilitato"
 msgid "Automatic forward enabled"
 msgstr "Avanzamento automatico abilitato"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Limiti del blocco nascosto"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "I limiti del blocco sono mostrati per tutti i blocchi"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "I limiti del blocco sono mostrati per il blocco attuale"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "I limiti del blocco sono mostrati per i blocchi vicini"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Aggiornamento telecamera disabilitato"
@@ -1279,6 +1275,12 @@ msgstr "Aggiornamento telecamera disabilitato"
 msgid "Camera update enabled"
 msgstr "Aggiornamento telecamera abilitato"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+"Impossibile mostrare i limiti del blocco (si ha bisogno del privilegio "
+"'baisc_debug')"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Cambia password"
@@ -1291,6 +1293,10 @@ msgstr "Modalità cinematica disabilitata"
 msgid "Cinematic mode enabled"
 msgstr "Modalità cinematica abilitata"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Client disconnesso"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Scripting su lato client disabilitato"
@@ -1299,6 +1305,10 @@ msgstr "Scripting su lato client disabilitato"
 msgid "Connecting to server..."
 msgstr "Connessione al server..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Connessione fallita per motivo sconosciuto"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Continua"
@@ -1336,6 +1346,11 @@ msgstr ""
 "- Rotella mouse: scegli oggetto\n"
 "- %s: chat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Impossibile risolvere l'indirizzo: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Creazione client..."
@@ -1465,9 +1480,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Minimappa attualmente disabilitata dal gioco o da una mod"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Gioco locale"
+msgstr "Multi giocatore"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1541,6 +1555,21 @@ msgstr "Il sistema audio non è supportato su questa build"
 msgid "Sound unmuted"
 msgstr "Suono attivato"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Il server sta probabilmente eseguendo una versione differente di %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Impossibile connettersi a %s perché IPv6 è disabilitato"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Impossibile ascoltare su %s perché IPv6 è disabilitato"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1875,6 +1904,14 @@ msgstr "Minimappa in modalità superficie, ingrandimento x%d"
 msgid "Minimap in texture mode"
 msgstr "Minimappa in modalità texture"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Impossibile aprire la pagina web"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Apertura pagina web"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Le password non corrispondono!"
@@ -1925,7 +1962,7 @@ msgstr "Indietreggia"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Limiti del blocco nascosto"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2077,8 +2114,9 @@ msgid "Muted"
 msgstr "Silenziato"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Volume suono: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Volume suono: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2342,6 +2380,12 @@ msgstr ""
 "Regola la configurazione dpi per il tuo schermo (solo non X11/Android) per "
 "es. per schermi 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Aggiusta la densità del display rilevato, utilizzato per scalare gli "
+"elementi UI."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2642,6 +2686,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Limite dei messaggi di chat per l'espulsione"
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Comandi della chat"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "Dimensione del carattere dell'area di messaggistica"
@@ -2675,8 +2723,9 @@ msgid "Chat toggle key"
 msgstr "Tasto di (dis)attivazione della chat"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Comandi della chat"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Chat visualizzata"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2694,6 +2743,14 @@ msgstr "Tasto modalità cinematic"
 msgid "Clean transparent textures"
 msgstr "Pulizia delle texture trasparenti"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Link web cliccabili (tasto-centrale o Ctrl+tasto-sinistro) abilitati nel "
+"output della chat."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Client"
@@ -2739,9 +2796,8 @@ msgid "Colored fog"
 msgstr "Nebbia colorata"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Nebbia colorata"
+msgstr "Ombre colorate"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2786,6 +2842,38 @@ msgstr ""
 msgid "Command key"
 msgstr "Tasto comando"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Livello di compressione ZLib da utilizzare quando si salvano i blocchi mappa "
+"su disco.\n"
+"-1 - Livello di compressione predefinito di Zlib\n"
+"0 - nessuna compressione, più veloce\n"
+"9 - migliore compressione, più lenta\n"
+"(i livelli 1-3 usano il metodo \"veloce\" di Zlib, 4-9 usano il metodo "
+"normale)"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Livello di compressione ZLib da utilizzare quando si inviano i blocchi mappa "
+"al client.\n"
+"-1 - Livello di compressione predefinito di Zlib\n"
+"0 - nessuna compressione, più veloce\n"
+"9 - migliore compressione, più lenta\n"
+"(i livelli 1-3 usano il metodo \"veloce\" di Zlib, 4-9 usano il metodo "
+"normale)"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Unire i vetri"
@@ -2886,9 +2974,10 @@ msgid "Crosshair alpha"
 msgstr "Trasparenza del mirino"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Trasparenza del mirino (opacità, tra 0 e 255).\n"
 "Controlla anche il colore del mirino dell'oggetto"
@@ -2971,10 +3060,14 @@ msgstr "Dimensione predefinita della pila"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Definisci la qualità del filtraggio delle ombre.\n"
+"Questo simula l'effetto delle ombre morbide applicando un PCF o Poisson "
+"disk\n"
+"ma utilizza più risorse."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3102,6 +3195,10 @@ msgstr "Disattiva anti-trucchi"
 msgid "Disallow empty passwords"
 msgstr "Rifiutare le password vuote"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Fattore di Scala della densità del display"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Nome di dominio del server, da mostrarsi nell'elenco dei server."
@@ -3153,9 +3250,21 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Abilità il filtraggio Poisson disk\n"
+"Se abilitato si hanno le \\\"ombre morbide\\\". Altrimenti utilizza il "
+"filtraggio PCF."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Abilità ombre colorate.\n"
+"Se abilitato nodi traslucidi producono ombre colorate. Questo è costoso."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3181,13 +3290,6 @@ msgstr "Abilita la sicurezza moduli"
 msgid "Enable players getting damage and dying."
 msgstr "Abilita il ferimento e la morte dei giocatori."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3306,6 +3408,12 @@ msgstr ""
 "nel gioco non saranno funzionanti.\n"
 "Cambiare questa impostazione richiede un riavvio."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Intervallo di stampa dei dati di profilo del motore di gioco"
@@ -3513,11 +3621,17 @@ msgid "Font size"
 msgstr "Dimensione del carattere"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Dimensione carattere del carattere predefinito, in punti (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Dimensione carattere del carattere a spaziatura fissa, in punti (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3529,6 +3643,17 @@ msgstr ""
 "punti (pt).\n"
 "Valore 0 userà la dimensione carattere predefinita."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3594,10 +3719,6 @@ msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 "Frazione della distanza visibile alla quale si comincia a disegnare la nebbia"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Caratteri FreeType"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3654,10 +3775,11 @@ msgid "Global callbacks"
 msgstr "Callback globali"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Attributi globali di generazione della mappa.\n"
 "In Mapgen v6 il valore 'decorations' controlla tutte le decorazioni eccetto "
@@ -3746,10 +3868,11 @@ msgid "Heat noise"
 msgstr "Rumore del calore"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Componente altezza della dimensione iniziale della finestra."
+msgstr ""
+"Componente altezza della dimensione iniziale della finestra. Ignorata in "
+"modalità a schermo intero."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -4106,6 +4229,9 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Se l'esecuzione del comando in chat impiega più tempo di quello specificato "
+"in\n"
+"secondi, aggiungi l'informazione sul tempo al messaggio di comando in chat"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4163,7 +4289,8 @@ msgstr ""
 "Questo normalmente serve solo ai contributori principali"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Predisporre i comandi della chat alla registrazione."
 
 #: src/settings_translation_file.cpp
@@ -4260,7 +4387,8 @@ msgid "Joystick button repetition interval"
 msgstr "Intervallo di ripetizione del pulsante del joystick"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+#, fuzzy
+msgid "Joystick dead zone"
 msgstr "Deadzone joystick"
 
 #: src/settings_translation_file.cpp
@@ -5386,9 +5514,8 @@ msgid "Map save interval"
 msgstr "Intervallo di salvataggio della mappa"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Scatto di aggiornamento del liquido"
+msgid "Map shadows update frames"
+msgstr "Frame di aggiornamento delle mappe d'ombra"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5502,7 +5629,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Distanza massima per renderizzare le ombre."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5638,19 +5765,20 @@ msgstr ""
 "della coda."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Tempo massimo in ms che può richiedere lo scaricamento di un file (es. un "
-"mod)."
+"Tempo massimo in millisecondi che può richiedere lo scaricamento di un file "
+"(es. un mod)."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Tempo massimo che può richiedere una richiesta interattiva (es. lista presa "
+"dal server), dichiarato in secondi."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5714,7 +5842,8 @@ msgid "Mod channels"
 msgstr "Canali mod"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "Modifica la dimensione degli elementi della barra dell'HUD."
 
 #: src/settings_translation_file.cpp
@@ -5725,6 +5854,11 @@ msgstr "Percorso del carattere a spaziatura fissa"
 msgid "Monospace font size"
 msgstr "Dimensione del carattere a spaziatura fissa"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Dimensione del carattere a spaziatura fissa"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Rumore dell'altezza montana"
@@ -5874,12 +6008,12 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Numero di blocchi extra che possono essere caricati da /clearobjects in una "
 "volta.\n"
-"Questo è un controbilanciare tra spesa di transazione sqlite e\n"
+"Questo è un compromesso tra spesa di transazione sqlite e\n"
 "consumo di memoria (4096 = 100MB, come regola generale)."
 
 #: src/settings_translation_file.cpp
@@ -5906,10 +6040,13 @@ msgstr ""
 "mette in pausa se è aperta una finestra di dialogo."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Sovrascrittura opzionale per i colori dei link web in chat."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5945,10 +6082,9 @@ msgstr ""
 "cercate a partire da qui."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Percorso del carattere predefinito.\n"
@@ -5960,10 +6096,9 @@ msgstr ""
 "caricato."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Percorso del carattere a spaziatura fissa.\n"
@@ -6027,9 +6162,8 @@ msgid "Player versus player"
 msgstr "Giocatore contro giocatore"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Filtraggio bilineare"
+msgstr "Filtraggio Poisson"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6085,11 +6219,12 @@ msgid "Prometheus listener address"
 msgstr "Indirizzo del listener Prometheus"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Indirizzo del listener Prometheus.\n"
 "Se Minetest viene compilato con l'opzione ENABLE_PROMETHEUS abilitata,\n"
@@ -6439,36 +6574,37 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Imposta l'intensità dell'ombra.\n"
+"Un valore basso significa avere ombre chiare, un valore alto significa avere "
+"ombre scure."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Imposta la dimensione del raggio delle ombre morbide.\n"
+"Valori bassi significano ombre nitide, valori alti significano ombre "
+"morbide.\n"
+"Valore minimo: 1.0; Valore massimo: 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Imposta l'inclinazione dell'orbita del Sole/Luna in gradi.\n"
+"Il valore 0 significa nessuna inclinazione/orbita verticale.\n"
+"Valore minimo: 0.0; valore massimo: 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Impostata su vero abilita le foglie ondeggianti.\n"
+"Impostata su vero abilita la Mappatura delle ombre.\n"
 "Necessita l'attivazione degli shader."
 
 #: src/settings_translation_file.cpp
@@ -6502,6 +6638,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Imposta la qualità della textura dell'ombra a 32 bit.\n"
+"Su falso, 16 bit di texture saranno utilizzati.\n"
+"Questo può causare molti più artefatti nell'ombra."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6520,22 +6659,21 @@ msgstr ""
 "Ciò funziona solo col supporto video OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Qualità degli screenshot"
+msgstr "Qualità filtro ombra"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
 msgstr ""
+"Distanza massima della mappa delle ombre nei nodi per renderizzare le ombre"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Texture della mappa delle ombre in 32 bit"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Dimensione minima della texture"
+msgstr "Dimensione della texture della mappa d'ombra"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6547,7 +6685,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Intensità dell'ombra"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6570,7 +6708,8 @@ msgstr ""
 "È necessario riavviare dopo aver cambiato questo."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+#, fuzzy
+msgid "Show name tag backgrounds by default"
 msgstr "Mostra lo sfondo del nome per impostazione predefinita"
 
 #: src/settings_translation_file.cpp
@@ -6670,9 +6809,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Velocità furtiva, in nodi al secondo."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Trasparenza dell'ombreggiatura del carattere"
+msgstr "Raggio dell'ombra morbida"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6701,6 +6839,19 @@ msgstr ""
 "Si noti che mod o giochi possono impostare esplicitamente una pila per "
 "alcuni (o tutti) gli oggetti."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Diffondi un aggiornamento completo della mappa d'ombra su un certo numero di "
+"frame.\n"
+"Valori alti potrebbero rendere le ombre laggose, valori bassi\n"
+"consumeranno più risorse.\n"
+"Valore minimo: 1; valore massimo: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6839,8 +6990,11 @@ msgstr "Percorso delle texture"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Dimensione della texture su cui renderizzare la mappa d'ombra.\n"
+"Questa deve essere una potenza di due.\n"
+"Valori alti creano ombre migliori ma è anche molto costoso."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6865,7 +7019,8 @@ msgid "The URL for the content repository"
 msgstr "L'URL per il deposito dei contenuti"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+#, fuzzy
+msgid "The dead zone of the joystick"
 msgstr "La deadzone del joystick"
 
 #: src/settings_translation_file.cpp
@@ -6941,7 +7096,6 @@ msgstr ""
 "active_object_send_range_blocks."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6950,17 +7104,19 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Il back-end di rendering per Irrlicht.\n"
+"Il rendering di back-end.\n"
 "Dopo averlo cambiato è necessario un riavvio.\n"
 "Nota: su Android, restare con OGLES1 se incerti! Altrimenti l'app potrebbe "
 "non partire.\n"
 "Su altre piattaforme, si raccomanda OpenGL\n"
-"Le shader sono supportate da OpenGL (solo su desktop) e OGLES2 (sperimentale)"
+"Gli shader sono supportati da OpenGL (solo su desktop) e OGLES2 "
+"(sperimentale)"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "La sensibilità degli assi del joystick per spostare\n"
 "il campo visivo durante il gioco."
@@ -7089,6 +7245,10 @@ msgstr "Ritardo dei suggerimenti"
 msgid "Touch screen threshold"
 msgstr "Soglia del touch screen"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Rumore degli alberi"
@@ -7170,8 +7330,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Usare il filtraggio bilineare quando si ridimensionano le texture."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7382,6 +7543,10 @@ msgstr "Lunghezza d'onda dei liquidi ondulanti"
 msgid "Waving plants"
 msgstr "Piante ondeggianti"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Colore del link web"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7406,13 +7571,12 @@ msgstr ""
 "non supportano correttamente lo scaricamento delle texture dall'hardware."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7422,30 +7586,20 @@ msgstr ""
 "possono essere sfocate, così viene eseguito l'ingrandimento automatico con "
 "l'interpolazione nearest-neighbor\n"
 "per conservare pixel chiari. Questo imposta la dimensione minima delle "
-"immagini\n"
+"texture\n"
 "per le texture ingrandite; valori più alti hanno un aspetto più nitido, ma "
 "richiedono più memoria.\n"
-"Sono raccomandate le potenze di 2. Impostarla a un valore maggiore di 1 "
-"potrebbe non avere\n"
-"un effetto visibile, a meno che il filtraggio bilineare/trilineare/"
-"anisotropico sia abilitato.\n"
+"Sono raccomandate le potenze di 2. Questa impostazione è SOLO applicabile "
+"se\n"
+"il filtraggio bilineare/trilineare/anisotropico è abilitato.\n"
 "Questo viene anche usato come dimensione di base per le immagini\n"
 "dei nodi per l'autoridimensionamento delle immagini con allineamento\n"
 "relativo al mondo."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Se si usano caratteri FreeType, richiede la compilazione col supporto "
-"FreeType.\n"
-"Se disabilitati, si utilizzano invece i caratteri bitmap e XML vettoriali."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 "Se lo sfondo del nome deve essere mostrato per impostazione predefinita.\n"
@@ -7503,9 +7657,10 @@ msgstr ""
 "premere F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Componente larghezza della dimensione iniziale della finestra."
+msgstr ""
+"Componente larghezza della dimensione iniziale della finestra. Ignorata in "
+"modalità a schermo intero."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7610,38 +7765,6 @@ msgstr "Livello Y del terreno inferiore e del fondale marino."
 msgid "Y-level of seabed."
 msgstr "Livello Y del fondale marino."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Livello di compressione ZLib da utilizzare quando si salvano i blocchi mappa "
-"su disco.\n"
-"-1 - Livello di compressione predefinito di Zlib\n"
-"0 - nessuna compressione, più veloce\n"
-"9 - migliore compressione, più lenta\n"
-"(i livelli 1-3 usano il metodo \"veloce\" di Zlib, 4-9 usano il metodo "
-"normale)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Livello di compressione ZLib da utilizzare quando si inviano i blocchi mappa "
-"al client.\n"
-"-1 - Livello di compressione predefinito di Zlib\n"
-"0 - nessuna compressione, più veloce\n"
-"9 - migliore compressione, più lenta\n"
-"(i livelli 1-3 usano il metodo \"veloce\" di Zlib, 4-9 usano il metodo "
-"normale)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Scadenza cURL scaricamento file"
@@ -7655,6 +7778,12 @@ msgstr "Scadenza cURL"
 msgid "cURL parallel limit"
 msgstr "Limite parallelo cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Modalità creativa: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Ferimento: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7838,6 +7967,9 @@ msgstr "Limite parallelo cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Dimensione carattere del carattere di ripiego, in punti (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Caratteri FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP dello schermo intero"
 
@@ -7856,6 +7988,9 @@ msgstr "Limite parallelo cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "Supporto IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Install: File: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Profondità della lava"
 
@@ -7988,6 +8123,9 @@ msgstr "Limite parallelo cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Questo carattere sarà usato per certe Lingue."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Per abilitare gli shader si deve usare il driver OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Scegli cinematica"
 
@@ -8011,6 +8149,15 @@ msgstr "Limite parallelo cURL"
 #~ msgid "Waving water"
 #~ msgstr "Acqua ondeggiante"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Se si usano caratteri FreeType, richiede la compilazione col supporto "
+#~ "FreeType.\n"
+#~ "Se disabilitati, si utilizzano invece i caratteri bitmap e XML vettoriali."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Se i sotterranei saltuariamente si protendono dal terreno."
 
@@ -8028,5 +8175,9 @@ msgstr "Limite parallelo cURL"
 #~ msgid "Yes"
 #~ msgstr "Sì"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Sei morto"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 541aea6599a3642acf244696d548ae88ba26772c..722f8a72843b119c100c147cdc5ba03349a50e52 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Japanese (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-04-08 18:26+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-29 21:28+0000\n"
 "Last-Translator: BreadW <toshiharu.uno@gmail.com>\n"
 "Language-Team: Japanese <https://hosted.weblate.org/projects/minetest/"
 "minetest/ja/>\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.6-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "アウトチャットキューの最大サイズ"
+msgstr "アウト チャット キューをクリアする"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "チャットコマンド"
+msgstr "空のコマンドです。"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "メインメニュー"
+msgstr "メインメニューに戻る"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "ローカルコマンド"
+msgstr "無効なコマンド: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "発行されたコマンド: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "ã\82·ã\83³ã\82°ã\83«ã\83\97ã\83¬ã\82¤ã\83¤ã\83¼"
+msgstr "ã\82ªã\83³ã\83©ã\82¤ã\83³ã\83\97ã\83¬ã\83¼ã\83¤ã\83¼ã\82\92ä¸\80覧表示ã\81\99ã\82\8b"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "ã\82·ã\83³ã\82°ã\83«ã\83\97ã\83¬ã\82¤ã\83¤ã\83¼"
+msgstr "ã\82ªã\83³ã\83©ã\82¤ã\83³ã\83\97ã\83¬ã\82¤ã\83¤ã\83¼ï¼\9a "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "アウトチャットキューは空になりました。"
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "このコマンドはサーバによって無効にされています。"
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,41 @@ msgstr "リスポーン"
 msgid "You died"
 msgstr "死んでしまった"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "死んでしまった"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "ローカルコマンド"
+msgstr "使用可能なコマンド:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "ローカルコマンド"
+msgstr "使用可能なコマンド: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "コマンドは使用できません: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "コマンドのヘルプを表示する"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"'.help <cmd>' を使用して詳細情報を取得するか、または '.help all' を使用してす"
+"べてを一覧表示します。"
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<利用できません>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Luaスクリプトでエラーが発生しました:"
@@ -118,7 +111,7 @@ msgstr "再接続"
 
 #: builtin/fstk/ui.lua
 msgid "The server has requested a reconnect:"
-msgstr "ã\82µã\83¼ã\83\90ã\81\8cå\86\8dæ\8e¥ç¶\9aã\82\92è¦\81æ±\82ã\81\97ã\81¾ã\81\97ã\81\9f:"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\81\8cå\86\8dæ\8e¥ç¶\9aã\82\92è¦\81æ±\82ã\81\97ã\81¾ã\81\97ã\81\9fï¼\9a"
 
 #: builtin/mainmenu/common.lua
 msgid "Protocol version mismatch. "
@@ -126,11 +119,11 @@ msgstr "プロトコルのバージョンが一致していません。 "
 
 #: builtin/mainmenu/common.lua
 msgid "Server enforces protocol version $1. "
-msgstr "サーバはバージョン$1のプロトコルを強制しています。 "
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\81¯ã\83\90ã\83¼ã\82¸ã\83§ã\83³$1ã\81®ã\83\97ã\83­ã\83\88ã\82³ã\83«ã\82\92å¼·å\88¶ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82 "
 
 #: builtin/mainmenu/common.lua
 msgid "Server supports protocol versions between $1 and $2. "
-msgstr "サーバは$1から$2までのプロトコルのバージョンをサポートしています。 "
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\81¯$1ã\81\8bã\82\89$2ã\81¾ã\81§ã\81®ã\83\97ã\83­ã\83\88ã\82³ã\83«ã\81®ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\82\92ã\82µã\83\9dã\83¼ã\83\88ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82 "
 
 #: builtin/mainmenu/common.lua
 msgid "We only support protocol version $1."
@@ -302,6 +295,10 @@ msgstr "$1 のインストール"
 msgid "Install missing dependencies"
 msgstr "不足依存Modインストール"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "インストール: 非対応のファイル形式か、壊れたアーカイブ"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -630,7 +627,7 @@ msgid "Offset"
 msgstr "オフセット"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "永続性"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -740,14 +737,6 @@ msgstr "Modインストール: 実際のMod名が見つかりません: $1"
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "Modインストール: Modパック $1 に適したフォルダ名が見つかりません"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "インストール: \"$1\"は非対応のファイル形式か、壊れたアーカイブです"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "インストール: ファイル: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "有効なModまたはModパックが見つかりません"
@@ -774,24 +763,23 @@ msgstr "読み込み中..."
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Public server list is disabled"
-msgstr "公開サーバ一覧は無効"
+msgstr "公開サーバ一覧は無効"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
-msgstr "インターネット接続を確認し、公開サーバ一覧を再有効化してください。"
+msgstr "インターネット接続を確認し、公開サーバ一覧を再有効化してください。"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "情報"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "活動中の貢献者"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "ã\82¢ã\82¯ã\83\86ã\82£ã\83\96ã\81ªã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88ã\81®é\80\81ä¿¡ç¯\84å\9b²"
+msgstr "ã\82¢ã\82¯ã\83\86ã\82£ã\83\96ã\81ªã\83¬ã\83³ã\83\80ã\83©ã\83¼ï¼\9a"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -859,7 +847,7 @@ msgstr "テクスチャパック使用"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Announce Server"
-msgstr "公開サーバ"
+msgstr "公開サーバ"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Bind Address"
@@ -879,7 +867,7 @@ msgstr "ゲームホスト"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Server"
-msgstr "ホストサーバ"
+msgstr "ホストサーバ"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Install games from ContentDB"
@@ -919,16 +907,15 @@ msgstr "ワールドを選択:"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Server Port"
-msgstr "サーバのポート"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\81®ã\83\9dã\83¼ã\83\88"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Start Game"
 msgstr "ゲームスタート"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- アドレス: "
+msgstr "アドレス"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -944,22 +931,20 @@ msgstr "クリエイティブモード"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "ダメージ"
+msgstr "ダメージ / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "お気に入り削除"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "お気に入り"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "互換性のないサーバ"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -970,18 +955,16 @@ msgid "Ping"
 msgstr "応答速度"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "公開サーバ"
+msgstr "公開サーバ"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "再読込"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "サーバ説明"
+msgstr "サーバーの説明"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1024,13 +1007,12 @@ msgid "Connected Glass"
 msgstr "ガラスを繋げる"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "フォントの影"
+msgstr "動的な影"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "動的な影: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1038,15 +1020,15 @@ msgstr "綺麗な葉"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "強め"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "弱め"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "普通"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1120,10 +1102,6 @@ msgstr "滑らかな光"
 msgid "Texturing:"
 msgstr "テクスチャリング:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "シェーダーを有効にするにはOpenGLのドライバを使用する必要があります。"
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "トーンマッピング"
@@ -1138,11 +1116,11 @@ msgstr "トライリニアフィルタ"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "超強く"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "とても弱く"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1156,7 +1134,7 @@ msgstr "揺れる液体"
 msgid "Waving Plants"
 msgstr "揺れる草花"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "接続がタイムアウトしました。"
 
@@ -1185,8 +1163,8 @@ msgid "Connection error (timed out?)"
 msgstr "接続エラー (タイムアウト?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "以下のゲームが見つからないか読み込めません \""
+msgid "Could not find or load game"
+msgstr "ゲームが見つからないか読み込めません: "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1228,14 +1206,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- アドレス: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- クリエイティブモード: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- ダメージ: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- モード: "
@@ -1246,7 +1216,7 @@ msgstr "- ポート: "
 
 #: src/client/game.cpp
 msgid "- Public: "
-msgstr "- 公開サーバ: "
+msgstr "- 公開サーバ: "
 
 #. ~ PvP = Player versus Player
 #: src/client/game.cpp
@@ -1255,7 +1225,16 @@ msgstr "- PvP: "
 
 #: src/client/game.cpp
 msgid "- Server Name: "
-msgstr "- サーバ名: "
+msgstr "- サーバー名: "
+
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "シリアライズエラーが発生しました:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "アクセスが拒否されました。理由: %s"
 
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
@@ -1265,6 +1244,22 @@ msgstr "自動前進 無効"
 msgid "Automatic forward enabled"
 msgstr "自動前進 有効"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "ブロック境界線を非表示"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "すべてのブロックにブロック境界線を表示"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "現在のブロックにブロック境界を表示"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "近くのブロックにブロック境界を表示"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "カメラ更新 無効"
@@ -1273,6 +1268,10 @@ msgstr "カメラ更新 無効"
 msgid "Camera update enabled"
 msgstr "カメラ更新 有効"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "ブロック境界線を表示できません ('basic_debug' 特権が必要です)"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "パスワード変更"
@@ -1285,13 +1284,21 @@ msgstr "映画風モード 無効"
 msgid "Cinematic mode enabled"
 msgstr "映画風モード 有効"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "クライアントが切断されました"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "クライアント側のスクリプトは無効"
 
 #: src/client/game.cpp
 msgid "Connecting to server..."
-msgstr "サーバに接続中..."
+msgstr "サーバーに接続中..."
+
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "未知の理由で接続に失敗しました"
 
 #: src/client/game.cpp
 msgid "Continue"
@@ -1330,13 +1337,18 @@ msgstr ""
 "- マウスホイール: アイテム選択\n"
 "- %s: チャット\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "アドレスを解決できませんでした: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "クライアントを作成中..."
 
 #: src/client/game.cpp
 msgid "Creating server..."
-msgstr "サーバを作成中..."
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\82\92ä½\9cæ\88\90中..."
 
 #: src/client/game.cpp
 msgid "Debug info and profiler graph hidden"
@@ -1436,7 +1448,7 @@ msgstr "ポーズメニュー"
 
 #: src/client/game.cpp
 msgid "Hosting server"
-msgstr "ホスティングサーバ"
+msgstr "ホスティングサーバ"
 
 #: src/client/game.cpp
 msgid "Item definitions..."
@@ -1459,9 +1471,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "ミニマップは現在ゲームまたはModにより無効"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "ã\82·ã\83³ã\82°ã\83«プレイヤー"
+msgstr "ã\83\9eã\83«ã\83\81プレイヤー"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1501,7 +1512,7 @@ msgstr "観測記録グラフ 表示"
 
 #: src/client/game.cpp
 msgid "Remote server"
-msgstr "リモートサーバ"
+msgstr "リモートサーバ"
 
 #: src/client/game.cpp
 msgid "Resolving address..."
@@ -1535,6 +1546,21 @@ msgstr "このビルドではサウンド システムがサポートされて
 msgid "Sound unmuted"
 msgstr "消音 取り消し"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "サーバーが別のバージョン %s を実行している可能性があります。"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "IPv6が無効なため、%sに接続できません"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "IPv6が無効なため、%sでリッスンできません"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1869,6 +1895,14 @@ msgstr "ミニマップ 表面モード、ズーム x%d"
 msgid "Minimap in texture mode"
 msgstr "ミニマップ テクスチャモード"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "ウェブページを開けませんでした"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "ウェブページを開いています"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "パスワードが一致しません!"
@@ -1886,8 +1920,8 @@ msgid ""
 "Please retype your password and click 'Register and Join' to confirm account "
 "creation, or click 'Cancel' to abort."
 msgstr ""
-"ã\81\82ã\81ªã\81\9fã\81¯ã\81\93ã\81®ã\82µã\83¼ã\83\90 ã\81«å\90\8då\89\8d \"%s\" ã\81§å\88\9dめて参加しようとしています。\n"
-"続行する場合、あなたの情報が新しいアカウントとしてこのサーバに作成されま"
+"ã\81\82ã\81ªã\81\9fã\81¯ã\81\93ã\81®ã\82µã\83¼ã\83\90 ã\83¼ã\81«å\90\8då\89\8d \"%s\" ã\81§ã\81¯ã\81\98めて参加しようとしています。\n"
+"ç¶\9aè¡\8cã\81\99ã\82\8bå ´å\90\88ã\80\81ã\81\82ã\81ªã\81\9fã\81®æ\83\85å ±ã\81\8cæ\96°ã\81\97ã\81\84ã\82¢ã\82«ã\82¦ã\83³ã\83\88ã\81¨ã\81\97ã\81¦ã\81\93ã\81®ã\82µã\83¼ã\83\90ã\83¼ã\81«ä½\9cæ\88\90ã\81\95ã\82\8cã\81¾"
 "す。\n"
 "あなたのパスワードを再入力してから '参加登録' をクリックしてアカウント作成す"
 "るか、\n"
@@ -1898,7 +1932,6 @@ msgid "Proceed"
 msgstr "決定"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
 msgstr "\"スペシャル\" = 降りる"
 
@@ -1912,7 +1945,7 @@ msgstr "自動ジャンプ"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1920,7 +1953,7 @@ msgstr "後退"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "ブロック境界線表示切替"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2073,8 +2106,9 @@ msgid "Muted"
 msgstr "消音"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "音量: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "音量: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2098,15 +2132,14 @@ msgstr ""
 "無効にした場合、最初に触れた位置がバーチャルパッドの中心になります。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) バーチャルパッドを使用して\"aux\"ボタンを起動します。\n"
+"(Android) バーチャルパッドを使用して\"Aux1\"ボタンを起動します。\n"
 "有効にした場合、バーチャルパッドはメインサークルから外れたときにも\n"
-"\"aux\"ボタンをタップします。"
+"\"Aux1\"ボタンをタップします。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2259,11 +2292,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server crashes."
-msgstr "ã\82µã\83¼ã\83\90ã\82¯ã\83©ã\83\83ã\82·ã\83¥æ\99\82ã\81«å\85¨てのクライアントへ表示するメッセージ。"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\82¯ã\83©ã\83\83ã\82·ã\83¥æ\99\82ã\81«ã\81\99ã\81¹てのクライアントへ表示するメッセージ。"
 
 #: src/settings_translation_file.cpp
 msgid "A message to be displayed to all clients when the server shuts down."
-msgstr "サーバ終了時に全てのクライアントへ表示するメッセージ。"
+msgstr "サーバー終了時にすべてのクライアントへ表示するメッセージ。"
 
 #: src/settings_translation_file.cpp
 msgid "ABM interval"
@@ -2308,7 +2341,7 @@ msgid ""
 "Note that the address field in the main menu overrides this setting."
 msgstr ""
 "接続先のアドレスです。\n"
-"ローカルサーバを起動する際は空白に設定してください。\n"
+"ã\83­ã\83¼ã\82«ã\83«ã\82µã\83¼ã\83\90ã\83¼ã\82\92èµ·å\8b\95ã\81\99ã\82\8bé\9a\9bã\81¯ç©ºç\99½ã\81«è¨­å®\9aã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82\n"
 "メインメニューのアドレス欄はこの設定を上書きすることに注意してください。"
 
 #: src/settings_translation_file.cpp
@@ -2322,6 +2355,11 @@ msgid ""
 msgstr ""
 "4kスクリーンなどのための、画面の解像度の設定です (非X11/Android環境のみ)。"
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"検出されたディスプレイの密度を調整し、UI要素のスケーリングに使用します。"
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2377,11 +2415,11 @@ msgstr "異方性フィルタリング"
 
 #: src/settings_translation_file.cpp
 msgid "Announce server"
-msgstr "サーバを公開"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\82\92å\85¬é\96\8b"
 
 #: src/settings_translation_file.cpp
 msgid "Announce to this serverlist."
-msgstr "このサーバ一覧に告知します。"
+msgstr "このサーバ一覧に告知します。"
 
 #: src/settings_translation_file.cpp
 msgid "Append item name"
@@ -2425,11 +2463,11 @@ msgid ""
 "optimization.\n"
 "Stated in mapblocks (16 nodes)."
 msgstr ""
-"この距離でサーバはどのブロックをクライアントへ送信するかを積極的に\n"
+"ã\81\93ã\81®è·\9dé\9b¢ã\81§ã\82µã\83¼ã\83\90ã\83¼ã\81¯ã\81©ã\81®ã\83\96ã\83­ã\83\83ã\82¯ã\82\92ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81¸é\80\81ä¿¡ã\81\99ã\82\8bã\81\8bã\82\92ç©\8d極ç\9a\84ã\81«\n"
 "最適化します。\n"
-"小さい値に設定すると、レンダリングの視覚的な不具合を犠牲にして、\n"
+"小さい値に設定すると、描画の視覚的な不具合を犠牲にして、\n"
 "パフォーマンスが大幅に向上する可能性があります(いくつかのブロックは\n"
-"水中や洞窟、時には陸の上でもレンダリングされません)。\n"
+"水中や洞窟、時には陸の上でも描画されません)。\n"
 "max_block_send_distance より大きい値に設定すると、この最適化は\n"
 "無効になります。 \n"
 "マップブロック(16ノード)で表記。"
@@ -2444,7 +2482,7 @@ msgstr "自動的に1ノードの障害物をジャンプします。"
 
 #: src/settings_translation_file.cpp
 msgid "Automatically report to the serverlist."
-msgstr "サーバ一覧に自動的に報告します。"
+msgstr "サーバ一覧に自動的に報告します。"
 
 #: src/settings_translation_file.cpp
 msgid "Autosave screen size"
@@ -2455,14 +2493,12 @@ msgid "Autoscaling mode"
 msgstr "自動拡大縮小モード"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "ジャンプキー"
+msgstr "Aux1キー"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "降りるためのスペシャルキー"
+msgstr "昇降用のAux1キー"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2614,9 +2650,12 @@ msgstr ""
 "0.0は最小光レベル、1.0は最大光レベルです。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "チャットメッセージキックのしきい値"
+msgstr "チャットコマンド時間切れメッセージのしきい値"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "チャットコマンド"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2651,8 +2690,8 @@ msgid "Chat toggle key"
 msgstr "チャット切替キー"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "ã\83\81ã\83£ã\83\83ã\83\88ã\82³ã\83\9eã\83³ã\83\89"
+msgid "Chat weblinks"
+msgstr "ã\83\81ã\83£ã\83\83ã\83\88ã\81®ã\82¦ã\82§ã\83\96ã\83ªã\83³ã\82¯"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2670,13 +2709,21 @@ msgstr "映画風モード切り替えキー"
 msgid "Clean transparent textures"
 msgstr "テクスチャの透過を削除"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"チャットコンソールの出力で、クリック可能なウェブリンク(中クリックまたはCtrl"
+"+左クリック)を有効になります。"
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "クライアント"
 
 #: src/settings_translation_file.cpp
 msgid "Client and Server"
-msgstr "クライアントとサーバ"
+msgstr "クライアントとサーバ"
 
 #: src/settings_translation_file.cpp
 msgid "Client modding"
@@ -2715,9 +2762,8 @@ msgid "Colored fog"
 msgstr "色つきの霧"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "色つきの"
+msgstr "色つきの"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2758,13 +2804,37 @@ msgstr ""
 msgid "Command key"
 msgstr "コマンドキー"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"マップブロックをディスクに保存するときに使用する圧縮レベル。\n"
+"-1 - 規定の圧縮レベルを使用\n"
+"0 - 最小の圧縮、最も速い\n"
+"9 - 最高の圧縮、最も遅い"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"マップブロックをクライアントに送信するときに使用する圧縮レベル。\n"
+"-1 - 規定の圧縮レベルを使用\n"
+"0 - 最小の圧縮、最も速い\n"
+"9 - 最高の圧縮、最も遅い"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "ガラスを繋げる"
 
 #: src/settings_translation_file.cpp
 msgid "Connect to external media server"
-msgstr "外部メディアサーバに接続"
+msgstr "å¤\96é\83¨ã\83¡ã\83\87ã\82£ã\82¢ã\82µã\83¼ã\83\90ã\83¼ã\81«æ\8e¥ç¶\9a"
 
 #: src/settings_translation_file.cpp
 msgid "Connects glass if supported by node."
@@ -2857,10 +2927,10 @@ msgstr "十字カーソルの透過度"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "十字カーソルの透過度(不透明、0~255の間)。\n"
-"ã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88å\8d\81å­\97ã\82«ã\83¼ã\82½ã\83«ã\81®è\89²ã\82\82å\88¶å¾¡"
+"ã\81\93ã\82\8cã\81¯ã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88ã\81®å\8d\81å­\97ã\82«ã\83¼ã\82½ã\83«ã\81«ã\82\82é\81©ç\94¨ã\81\95ã\82\8cã\81¾ã\81\99ã\80\82"
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2904,7 +2974,7 @@ msgstr "この値を小さくすると、移動時の液体抵抗が増加しま
 
 #: src/settings_translation_file.cpp
 msgid "Dedicated server step"
-msgstr "専用サーバステップ"
+msgstr "å°\82ç\94¨ã\82µã\83¼ã\83\90ã\83¼ã\82¹ã\83\86ã\83\83ã\83\97"
 
 #: src/settings_translation_file.cpp
 msgid "Default acceleration"
@@ -2940,10 +3010,14 @@ msgstr "既定のスタック数"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"影フィルタの品質を定義します。\n"
+"これは、PCFまたはポアソンディスクを適用することで、やわらない影効果をシミュ"
+"レートするものです。\n"
+"しかし、より多くのリソースを消費します。"
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3029,7 +3103,7 @@ msgstr "これ以下の深さで大きな洞窟が見つかります。"
 msgid ""
 "Description of server, to be displayed when players join and in the "
 "serverlist."
-msgstr "ã\82µã\83¼ã\83\90ã\81®èª¬æ\98\8eã\80\82ã\83\97ã\83¬ã\82¤ã\83¤ã\83¼ã\81\8cå\8f\82å\8a ã\81\97ã\81\9fã\81¨ã\81\8dã\81¨ã\82µã\83¼ã\83\90一覧に表示されます。"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\81®èª¬æ\98\8eã\80\82ã\83\97ã\83¬ã\82¤ã\83¤ã\83¼ã\81\8cå\8f\82å\8a ã\81\97ã\81\9fã\81¨ã\81\8dã\81¨ã\82µã\83¼ã\83\90ã\83¼一覧に表示されます。"
 
 #: src/settings_translation_file.cpp
 msgid "Desert noise threshold"
@@ -3063,9 +3137,13 @@ msgstr "対チート機関無効化"
 msgid "Disallow empty passwords"
 msgstr "空のパスワードを許可しない"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "ディスプレイ密度スケーリング係数"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
-msgstr "サーバ一覧に表示されるサーバのドメイン名。"
+msgstr "サーバー一覧に表示されるサーバーのドメイン名。"
 
 #: src/settings_translation_file.cpp
 msgid "Double tap jump for fly"
@@ -3113,9 +3191,21 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"ポアソンディスクによるフィルタリングを有効にします。\n"
+"true の場合、ポアソンディスクを使用して「やわらない影」を作ります。それ以外の"
+"場合は、PCFフィルタリングを使用します。"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"色つきの影を有効にします。\n"
+"真の半透明ノードでは、色つきの影を落とします。これは負荷が大きいです。"
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3141,13 +3231,6 @@ msgstr "Modのセキュリティを有効化"
 msgid "Enable players getting damage and dying."
 msgstr "プレイヤーがダメージを受けて死亡するのを有効にします。"
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "ランダムなユーザー入力を有効にします (テストにのみ使用)。"
@@ -3161,7 +3244,7 @@ msgid ""
 "Enable register confirmation when connecting to server.\n"
 "If disabled, new account will be registered automatically."
 msgstr ""
-"サーバへの接続時に登録確認を有効にします。\n"
+"ã\82µã\83¼ã\83\90ã\83¼ã\81¸ã\81®æ\8e¥ç¶\9aæ\99\82ã\81«ç\99»é\8c²ç¢ºèª\8dã\82\92æ\9c\89å\8a¹ã\81«ã\81\97ã\81¾ã\81\99ã\80\82\n"
 "無効にすると、新しいアカウントが自動的に登録されます。"
 
 #: src/settings_translation_file.cpp
@@ -3181,7 +3264,7 @@ msgid ""
 "expecting."
 msgstr ""
 "古いクライアントが接続できないようにします。\n"
-"古いクライアントは新しいサーバに接続してもクラッシュしないという\n"
+"å\8f¤ã\81\84ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81¯æ\96°ã\81\97ã\81\84ã\82µã\83¼ã\83\90ã\83¼ã\81«æ\8e¥ç¶\9aã\81\97ã\81¦ã\82\82ã\82¯ã\83©ã\83\83ã\82·ã\83¥ã\81\97ã\81ªã\81\84ã\81¨ã\81\84ã\81\86\n"
 "意味で互換性がありますが、期待しているすべての新機能をサポート\n"
 "しているわけではありません。"
 
@@ -3192,9 +3275,9 @@ msgid ""
 "textures)\n"
 "when connecting to the server."
 msgstr ""
-"ã\83ªã\83¢ã\83¼ã\83\88ã\83¡ã\83\87ã\82£ã\82¢ã\82µã\83¼ã\83\90ã\81®ä½¿ç\94¨ã\82\92æ\9c\89å\8a¹ã\81«ã\81\97ã\81¾ã\81\99 (ã\82µã\83¼ã\83\90によって提供\n"
+"ã\83ªã\83¢ã\83¼ã\83\88ã\83¡ã\83\87ã\82£ã\82¢ã\82µã\83¼ã\83\90ã\83¼ã\81®ä½¿ç\94¨ã\82\92æ\9c\89å\8a¹ã\81«ã\81\97ã\81¾ã\81\99 (ã\82µã\83¼ã\83\90ã\83¼によって提供\n"
 "されている場合)。\n"
-"リモートサーバはサーバに接続するときにメディア (例えば、テクスチャ) を\n"
+"ã\83ªã\83¢ã\83¼ã\83\88ã\82µã\83¼ã\83\90ã\81¯ã\82µã\83¼ã\83\90ã\83¼ã\81«æ\8e¥ç¶\9aã\81\99ã\82\8bã\81¨ã\81\8dã\81«ã\83¡ã\83\87ã\82£ã\82¢ (ä¾\8bã\81\88ã\81°ã\80\81ã\83\86ã\82¯ã\82¹ã\83\81ã\83£) ã\82\92\n"
 "ダウンロードするための非常に高速な方法を提供します。"
 
 #: src/settings_translation_file.cpp
@@ -3259,6 +3342,14 @@ msgstr ""
 "ゲーム内の音の制御は機能しなくなります。\n"
 "この設定を変更するには再起動が必要です。"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+"ゲームのプレイアビリティに影響を与えない小さな視覚的な不具合を犠牲にして\n"
+"CPU負荷を軽減するか、レンダリングパフォーマンスを向上させるトレードオフを有効にします。"
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "エンジンプロファイリングデータの出力間隔"
@@ -3320,13 +3411,12 @@ msgid "Fast movement"
 msgstr "高速移動モード"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"高速移動 (\"スペシャル\"キーによる)。\n"
-"これにはサーバ上に \"fast\" 特権が必要です。"
+"高速移動 (\"Aux1\"キーによる)。\n"
+"これにはサーバ上に \"fast\" 特権が必要です。"
 
 #: src/settings_translation_file.cpp
 msgid "Field of view"
@@ -3343,7 +3433,7 @@ msgid ""
 "Multiplayer Tab."
 msgstr ""
 "client/serverlist/ フォルダ内のファイルで、ゲームに参加タブで表示されている\n"
-"お気に入りのサーバが含まれています。"
+"ã\81\8aæ°\97ã\81«å\85¥ã\82\8aã\81®ã\82µã\83¼ã\83\90ã\83¼ã\81\8cå\90«ã\81¾ã\82\8cã\81¦ã\81\84ã\81¾ã\81\99ã\80\82"
 
 #: src/settings_translation_file.cpp
 msgid "Filler depth"
@@ -3358,17 +3448,17 @@ msgid "Filmic tone mapping"
 msgstr "フィルム調トーンマッピング"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
 "light edges to transparent textures. Apply a filter to clean that up\n"
 "at texture load time. This is automatically enabled if mipmapping is enabled."
 msgstr ""
-"フィルタ処理されたテクスチャはRGB値と完全に透明な隣り合うものと混ぜる\n"
-"ことができます。PNGオプティマイザは通常これを破棄します。その結果、\n"
-"透明なテクスチャに対して暗いまたは明るいエッジが生じることがあります。\n"
-"このフィルタを適用してテクスチャ読み込み時にそれをきれいにします。"
+"フィルタ処理されたテクスチャは、RGB値を完全に透明な隣り合うものと\n"
+"混ぜることができます。これはPNGオプティマイザーが通常廃棄するもので、\n"
+"透過テクスチャの端が暗くなったり明るくなったりすることがよくあります。\n"
+"テクスチャの読み込み時にフィルタを適用してそれをきれいにします。\n"
+"これはミップマッピングが有効な場合に自動的に有効になります。"
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3459,12 +3549,16 @@ msgid "Font size"
 msgstr "フォントの大きさ"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
-msgstr "既定のフォントのフォント サイズ (pt)。"
+msgid "Font size divisible by"
+msgstr "割り切れるフォントサイズ"
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "96 DPIで1ユニット=1ピクセルとなる既定のフォントのフォントサイズ"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr "固定幅フォントのフォントサイズ (pt)。"
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "96 DPIで1ユニット=1ピクセルとなる固定幅フォントのフォントサイズ"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3474,6 +3568,21 @@ msgstr ""
 "最近のチャットテキストとチャットプロンプトのフォントサイズ(ポイント)。\n"
 "値 0 は規定のフォントサイズを使用します。"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+"拡大縮小がうまくいかないピクセルスタイルのフォントの場合、このフォントで\n"
+"使用されるフォントサイズは、常にこの値で割り切れます。例えば高さ16ピクセルの\n"
+"ピクセルフォントの場合、この値を16に設定すると、16、32、48などのサイズにしか\n"
+"なりませんので、25のサイズを要求したMODは32を取得します。"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3534,11 +3643,7 @@ msgstr "フラクタルの種類"
 
 #: src/settings_translation_file.cpp
 msgid "Fraction of the visible distance at which fog starts to be rendered"
-msgstr "霧がレンダリングされ始める可視距離の割合"
-
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "フリータイプフォント"
+msgstr "霧が描画され始める可視距離の割合"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3566,7 +3671,7 @@ msgstr ""
 "クライアントがどれくらいの距離のオブジェクトを知っているか、\n"
 "マップブロック(16ノード)で定めます。\n"
 "\n"
-"これを active_block_range よりも大きく設定すると、サーバは\n"
+"ã\81\93ã\82\8cã\82\92 active_block_range ã\82\88ã\82\8aã\82\82大ã\81\8dã\81\8f設å®\9aã\81\99ã\82\8bã\81¨ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯\n"
 "この距離までプレーヤーが見ている方向に\n"
 "アクティブなオブジェクトを維持します。(これによりモブが突然\n"
 "視野から消えるのを避けることができます)"
@@ -3599,10 +3704,10 @@ msgstr "グローバルコールバック"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
-"グローバルマップ生成属性。\n"
-"ã\83\9eã\83\83ã\83\97ã\82¸ã\82§ã\83\8dã\83¬ã\83¼ã\82¿v6ã\81§ã\81¯ã\80\81'decorations' ã\83\95ã\83©ã\82°ã\81¯木とジャングルの草を\n"
+"全体的なマップ生成属性。\n"
+"ã\83\9eã\83\83ã\83\97ã\82¸ã\82§ã\83\8dã\83¬ã\83¼ã\82¿v6ã\81§ã\81¯ã\80\81'decorations' ã\83\95ã\83©ã\82°ã\81§木とジャングルの草を\n"
 "除くすべての装飾を制御しますが、他のすべてのマップジェネレータでは\n"
 "このフラグがすべての装飾を制御します。"
 
@@ -3685,10 +3790,9 @@ msgid "Heat noise"
 msgstr "熱ノイズ"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "ウィンドウ高さの初期値。"
+msgstr "初期ウィンドウサイズの高さ。フルスクリーンモードでは無視されます。"
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3724,7 +3828,7 @@ msgstr "丘陵性4ノイズ"
 
 #: src/settings_translation_file.cpp
 msgid "Homepage of server, to be displayed in the serverlist."
-msgstr "サーバ一覧に表示されるサーバのホームページ。"
+msgstr "サーバ一覧に表示されるサーバのホームページ。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3905,7 +4009,7 @@ msgid ""
 "How much the server will wait before unloading unused mapblocks.\n"
 "Higher value is smoother, but will use more RAM."
 msgstr ""
-"未使用のマップブロックをアンロードするまでにサーバが待機する量。\n"
+"未使用のマップブロックを破棄するまでにサーバーが待機する量。\n"
 "値が大きいほど滑らかになりますが、より多くのRAMが使用されます。"
 
 #: src/settings_translation_file.cpp
@@ -3930,7 +4034,7 @@ msgstr "IPv6"
 
 #: src/settings_translation_file.cpp
 msgid "IPv6 server"
-msgstr "IPv6 サーバ"
+msgstr "IPv6 サーバ"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3941,13 +4045,12 @@ msgstr ""
 "スリープ状態で制限します。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
 "無効になっている場合、飛行モードと高速移動モードの両方が有効になって\n"
-"いると、\"ã\82¹ã\83\9aã\82·ã\83£ã\83«\"ã\82­ã\83¼ã\82\92使ç\94¨ã\81\97ã\81¦é«\98é\80\9fã\81§é£\9bè¡\8cã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99ã\80\82"
+"いると、\"Aux1\"ã\82­ã\83¼ã\82\92使ç\94¨ã\81\97ã\81¦é«\98é\80\9fã\81§é£\9bè¡\8cã\81§ã\81\8dã\81¾ã\81\99ã\80\82"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3957,7 +4060,7 @@ msgid ""
 "invisible\n"
 "so that the utility of noclip mode is reduced."
 msgstr ""
-"有効にすると、サーバはプレーヤーの目の位置に基づいてマップブロック\n"
+"æ\9c\89å\8a¹ã\81«ã\81\99ã\82\8bã\81¨ã\80\81ã\82µã\83¼ã\83\90ã\83¼ã\81¯ã\83\97ã\83¬ã\83¼ã\83¤ã\83¼ã\81®ç\9b®ã\81®ä½\8dç½®ã\81«å\9fºã\81¥ã\81\84ã\81¦ã\83\9eã\83\83ã\83\97ã\83\96ã\83­ã\83\83ã\82¯\n"
 "オクルージョンカリングを実行します。これによりクライアントに送信される\n"
 "ブロック数を50〜80%減らすことができます。すり抜けモードの有用性が\n"
 "減るように、クライアントはもはや目に見えないものを受け取りません。"
@@ -3973,14 +4076,13 @@ msgstr ""
 "これにはサーバー上に \"noclip\" 特権が必要です。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"有効にすると、降りるときや水中を潜るとき \"スニーク\" キーの代りに \n"
-"\"スペシャル\" キーが使用されます。"
+"有効にすると、降りるとき \"スニーク\" キーの代りに \n"
+"\"Aux1\" キーが使用されます。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3988,7 +4090,7 @@ msgid ""
 "This option is only read when server starts."
 msgstr ""
 "有効にした場合、ロールバックのために行動が記録されます。\n"
-"このオプションはサーバ起動時にのみ読み込まれます。"
+"このオプションはサーバ起動時にのみ読み込まれます。"
 
 #: src/settings_translation_file.cpp
 msgid "If enabled, disable cheat prevention in multiplayer."
@@ -3999,7 +4101,7 @@ msgid ""
 "If enabled, invalid world data won't cause the server to shut down.\n"
 "Only enable this if you know what you are doing."
 msgstr ""
-"有効にした場合、無効なワールドデータによってサーバがシャットダウン\n"
+"æ\9c\89å\8a¹ã\81«ã\81\97ã\81\9få ´å\90\88ã\80\81ç\84¡å\8a¹ã\81ªã\83¯ã\83¼ã\83«ã\83\89ã\83\87ã\83¼ã\82¿ã\81«ã\82\88ã\81£ã\81¦ã\82µã\83¼ã\83\90ã\83¼ã\81\8cã\82·ã\83£ã\83\83ã\83\88ã\83\80ã\82¦ã\83³\n"
 "することはありません。\n"
 "自分がしていることがわかっている場合のみこれを有効にします。"
 
@@ -4039,6 +4141,8 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"チャットコマンドの実行が、この指定された時間(秒)よりも長くかかる場合は\n"
+"チャットコマンドのメッセージに時間の情報を追加します。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4093,7 +4197,7 @@ msgstr ""
 "これは通常、コア/ビルトイン貢献者にのみ必要"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr "チャットコマンドが登録されるとすぐに計測します。"
 
 #: src/settings_translation_file.cpp
@@ -4187,7 +4291,7 @@ msgid "Joystick button repetition interval"
 msgstr "ジョイスティックボタンの繰り返し間隔"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "ジョイスティックのデッドゾーン"
 
 #: src/settings_translation_file.cpp
@@ -5049,7 +5153,8 @@ msgid ""
 "Length of a server tick and the interval at which objects are generally "
 "updated over\n"
 "network."
-msgstr "サーバの間隔の長さとオブジェクトが通常ネットワーク上で更新される間隔。"
+msgstr ""
+"サーバーが時を刻む間隔とオブジェクトが通常ネットワーク上で更新される間隔。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5134,8 +5239,8 @@ msgid ""
 "Only has an effect if compiled with cURL."
 msgstr ""
 "並列HTTPリクエストの数を制限します。影響:\n"
-"-    サーバが remote_media 設定を使用している場合はメディアの取得。\n"
-"-    サーバ一覧のダウンロードとサーバの公開。\n"
+"-    ã\82µã\83¼ã\83\90ã\83¼ã\81\8c remote_media è¨­å®\9aã\82\92使ç\94¨ã\81\97ã\81¦ã\81\84ã\82\8bå ´å\90\88ã\81¯ã\83¡ã\83\87ã\82£ã\82¢ã\81®å\8f\96å¾\97ã\80\82\n"
+"-    サーバ一覧のダウンロードとサーバの公開。\n"
 "-    メインメニューで実行されたダウンロード(例えば、コンテンツ)。\n"
 "cURLでコンパイルされた場合にのみ効果があります。"
 
@@ -5179,7 +5284,7 @@ msgid ""
 msgstr ""
 "ゲームの観測記録を読み込んで、ゲームの観測データを収集します。\n"
 "集められた観測記録にアクセスするための /profiler コマンドを提供します。\n"
-"Mod開発者やサーバオペレーターに役立ちます。"
+"Modé\96\8bç\99ºè\80\85ã\82\84ã\82µã\83¼ã\83\90ã\83¼ã\82ªã\83\9aã\83¬ã\83¼ã\82¿ã\83¼ã\81«å½¹ç«\8bã\81¡ã\81¾ã\81\99ã\80\82"
 
 #: src/settings_translation_file.cpp
 msgid "Loading Block Modifiers"
@@ -5293,9 +5398,8 @@ msgid "Map save interval"
 msgstr "マップ保存間隔"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "液体の更新間隔"
+msgid "Map shadows update frames"
+msgstr "地図の影の更新フレーム"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5311,7 +5415,7 @@ msgstr "メッシュ生成のマップブロックキャッシュサイズ(MB)"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock unload timeout"
-msgstr "マップブロックアンロードタイムアウト"
+msgstr "マップブロック破棄タイムアウト"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen Carpathian"
@@ -5409,7 +5513,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "影を描画する最大距離。"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5536,17 +5640,20 @@ msgstr ""
 "キューを無効にするには 0、サイズを無制限にするには -1 を指定します。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
-msgstr "ファイルダウンロード (例: Modのダウンロード)の最大経過時間。"
+msgstr ""
+"ファイルダウンロード(Modのダウンロードなど)にかかる最大時間をミリ秒単位で指"
+"定します。"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"インタラクティブリクエスト(サーバー一覧の取得など)にかかる最大時間をミリ秒"
+"単位で指定します。"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5609,8 +5716,8 @@ msgid "Mod channels"
 msgstr "Modチャンネル"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "HUDバー要素のサイズを変更します。"
+msgid "Modifies the size of the HUD elements."
+msgstr "HUD要素のサイズを変更します。"
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
@@ -5620,6 +5727,10 @@ msgstr "固定幅フォントのパス"
 msgid "Monospace font size"
 msgstr "固定幅フォントのサイズ"
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr "割り切れる固定幅フォントのサイズ"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "山の高さノイズ"
@@ -5683,14 +5794,14 @@ msgid ""
 "When starting from the main menu, this is overridden."
 msgstr ""
 "プレイヤーの名前。\n"
-"サーバを実行している場合、この名前で接続しているクライアントは管理者\n"
+"ã\82µã\83¼ã\83\90ã\83¼ã\82\92å®\9fè¡\8cã\81\97ã\81¦ã\81\84ã\82\8bå ´å\90\88ã\80\81ã\81\93ã\81®å\90\8då\89\8dã\81§æ\8e¥ç¶\9aã\81\97ã\81¦ã\81\84ã\82\8bã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88ã\81¯ç®¡ç\90\86è\80\85\n"
 "です。\n"
 "メインメニューから起動すると、これは上書きされます。"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Name of the server, to be displayed when players join and in the serverlist."
-msgstr "プレイヤーが参加したときにサーバ一覧に表示されるサーバの名前。"
+msgstr "プレイヤーが参加したときにサーバー一覧に表示されるサーバーの名前。"
 
 #: src/settings_translation_file.cpp
 msgid "Near plane"
@@ -5764,12 +5875,12 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
-"一度に /clearobjects によってロードできる追加ブロックの数。\n"
+"/clearobjects によって一度に読み込みできる追加ブロックの数です。\n"
 "これは、SQLiteトランザクションのオーバーヘッドとメモリ消費の間の\n"
-"トレードオフです (経験則として、4096 = 100MB)。"
+"トレードオフです (大体 4096 = 100MB)。"
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
@@ -5793,21 +5904,18 @@ msgstr ""
 "ウィンドウのフォーカスが失われたときにポーズメニューを開きます。\n"
 "フォームスペックが開かれているときはポーズメニューを開きません。"
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "チャットのウェブリンクの色を上書きするオプションです。"
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
-"フォールバックフォントのパス。\n"
-"「フリータイプフォント」が有効な場合:TrueTypeフォントでなければなりませ"
-"ん。\n"
-"「フリータイプフォント」が無効な場合:ビットマップまたはXMLベクターフォント\n"
-"でなければなりません。\n"
-"このフォントは特定の言語で使用されるか、規定のフォントが使用できない\n"
-"ときに使用されます。"
+"フォールバックフォントのパス。TrueType フォントでなければなりません。\n"
+"このフォントは特定の言語か、規定のフォントが使用できないときに使用されます。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5833,30 +5941,18 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
-"既定のフォントのパス。\n"
-"「フリータイプフォント」が有効な場合:TrueTypeフォントでなければなりませ"
-"ん。\n"
-"「フリータイプフォント」が無効な場合:ビットマップまたはXMLベクターフォント\n"
-"でなければなりません。\n"
+"既定のフォントのパス。TrueType フォントでなければなりません。\n"
 "このフォールバックフォントはフォントが読み込めないときに使用されます。"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
-"固定幅フォントのパス。\n"
-"「フリータイプフォント」が有効な場合:TrueTypeフォントでなければなりませ"
-"ん。\n"
-"「フリータイプフォント」が無効な場合:ビットマップまたはXMLベクターフォント\n"
-"でなければなりません。\n"
+"固定幅フォントのパス。TrueType フォントでなければなりません。\n"
 "このフォントはコンソールや観測記録画面などで使用されます。"
 
 #: src/settings_translation_file.cpp
@@ -5912,9 +6008,8 @@ msgid "Player versus player"
 msgstr "プレイヤー対プレイヤー"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "ã\83\90ã\82¤ã\83ªã\83\8bã\82¢フィルタリング"
+msgstr "ã\83\9dã\82¢ã\82½ã\83³フィルタリング"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5967,15 +6062,15 @@ msgstr "プロメテウスリスナーのアドレス"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "プロメテウスリスナーのアドレス。\n"
-"minetest が ENABLE_PROMETHEUS オプションを有効にしてコンパイルされている場"
+"Minetest が ENABLE_PROMETHEUS オプションを有効にしてコンパイルされている場"
 "合、\n"
 "そのアドレスのプロメテウスのメトリックスリスナーを有効にします。\n"
-"メトリックは http://127.0.0.1:30000/metrics で取得可能"
+"ã\83¡ã\83\88ã\83ªã\83\83ã\82¯ã\82¹ã\81¯ http://127.0.0.1:30000/metrics ã\81§å\8f\96å¾\97å\8f¯è\83½"
 
 #: src/settings_translation_file.cpp
 msgid "Proportion of large caves that contain liquid."
@@ -6048,7 +6143,7 @@ msgid ""
 "csm_restriction_noderange)\n"
 "READ_PLAYERINFO: 32 (disable get_player_names call client-side)"
 msgstr ""
-"サーバで特定のクライアント側機能へのアクセスを制限します。\n"
+"ã\82µã\83¼ã\83\90ã\83¼ã\81§ç\89¹å®\9aã\81®ã\82¯ã\83©ã\82¤ã\82¢ã\83³ã\83\88å\81´æ©\9fè\83½ã\81¸ã\81®ã\82¢ã\82¯ã\82»ã\82¹ã\82\92å\88¶é\99\90ã\81\97ã\81¾ã\81\99ã\80\82\n"
 "以下の byteflags を合わせてクライアント側の機能を制限するか、制限なしの\n"
 "場合は 0 に設定します。\n"
 "LOAD_CLIENT_MODS: 1 (クライアント提供のModの読み込みを無効)\n"
@@ -6137,7 +6232,7 @@ msgstr "ウィンドウサイズ変更時に自動的に保存します。"
 
 #: src/settings_translation_file.cpp
 msgid "Saving map received from server"
-msgstr "サーバから受信したマップ保存"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\81\8bã\82\89å\8f\97ä¿¡ã\81\97ã\81\9fã\83\9eã\83\83ã\83\97ä¿\9då­\98"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6259,39 +6354,39 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Server / Singleplayer"
-msgstr "サーバ / シングルプレイヤー"
+msgstr "サーバ / シングルプレイヤー"
 
 #: src/settings_translation_file.cpp
 msgid "Server URL"
-msgstr "サーバURL"
+msgstr "サーバURL"
 
 #: src/settings_translation_file.cpp
 msgid "Server address"
-msgstr "サーバアドレス"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\82¢ã\83\89ã\83¬ã\82¹"
 
 #: src/settings_translation_file.cpp
 msgid "Server description"
-msgstr "サーバ説明"
+msgstr "サーバ説明"
 
 #: src/settings_translation_file.cpp
 msgid "Server name"
-msgstr "サーバ名"
+msgstr "サーバ名"
 
 #: src/settings_translation_file.cpp
 msgid "Server port"
-msgstr "サーバポート"
+msgstr "ã\82µã\83¼ã\83\90ã\83¼ã\83\9dã\83¼ã\83\88"
 
 #: src/settings_translation_file.cpp
 msgid "Server side occlusion culling"
-msgstr "サーバ側のオクルージョンカリング"
+msgstr "サーバ側のオクルージョンカリング"
 
 #: src/settings_translation_file.cpp
 msgid "Serverlist URL"
-msgstr "サーバ一覧URL"
+msgstr "サーバ一覧URL"
 
 #: src/settings_translation_file.cpp
 msgid "Serverlist file"
-msgstr "サーバ一覧ファイル"
+msgstr "サーバ一覧ファイル"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6310,36 +6405,35 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"影の強さを設定します。\n"
+"値が小さいほど影が薄く、値が大きいほど影が濃くなります。"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"やわらない影の半径サイズを設定します。\n"
+"値が小さいほどシャープな影、大きいほどやわらない影になります。\n"
+"最小値: 1.0、最大値: 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"太陽/月の軌道の傾きを度数で設定します。\n"
+"0 は傾きのない垂直な軌道です。\n"
+"最小値: 0.0、最大値: 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"有効にすると葉が揺れます。\n"
+"有効にすると影を映します。\n"
 "シェーダーが有効である必要があります。"
 
 #: src/settings_translation_file.cpp
@@ -6372,6 +6466,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"影のテクスチャの品質を 32 ビットに設定します。\n"
+"false の場合、16ビットのテクスチャが使用されます。\n"
+"これは、影がさら不自然になる可能性があります。"
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6389,22 +6486,20 @@ msgstr ""
 "これはOpenGLビデオバックエンドでのみ機能します。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "スクリーンショットの品質"
+msgstr "影フィルタの品質"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "影を描画するためのノードの最大距離"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "32ビットの影投影テクスチャ"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "最小テクスチャサイズ"
+msgstr "影投影テクスチャサイズ"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6416,7 +6511,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "影の強さ"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6439,12 +6534,12 @@ msgstr ""
 "変更後は再起動が必要です。"
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
-msgstr "既定でネームタグの背景を表示"
+msgid "Show name tag backgrounds by default"
+msgstr "ネームタグの背景を既定で表示"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
-msgstr "サーバ終了時のメッセージ"
+msgstr "サーバ終了時のメッセージ"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6474,7 +6569,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "天体の軌道傾斜角"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6534,9 +6629,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "スニーク時の速度、1秒あたりのノード数です。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "ã\83\95ã\82©ã\83³ã\83\88ã\81®å½±ã\81®é\80\8fé\81\8e"
+msgstr "ã\82\84ã\82\8fã\82\89ã\81ªã\81\84å½±å\8d\8aå¾\84"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6564,6 +6658,18 @@ msgstr ""
 "Mod またはゲームは、特定の(またはすべての)アイテムのスタック数を\n"
 "明示的に設定する場合があることに注意してください。"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"影の描画の完全な更新を指定されたフレーム数に広げます。\n"
+"値を大きくすると影が遅延することがあり、値を小さくすると\n"
+"より多くのリソースを消費します。\n"
+"最小値: 1、最大値: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6696,8 +6802,11 @@ msgstr "テクスチャパス"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"影を描画するためのテクスチャサイズです。\n"
+"これは2の累乗でなければなりません。\n"
+"数字が大きいほどより良い影ができますが、負荷も高くなります。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6712,7 +6821,7 @@ msgstr ""
 "ことができます。\n"
 "前者のモードは、機械、家具などのようなものに適していますが、\n"
 "後者のモードは階段やマイクロブロックを周囲の環境に合わせやすくします。\n"
-"しかし、この機能は新しく、古いサーバでは使用できない可能性があります。\n"
+"ã\81\97ã\81\8bã\81\97ã\80\81ã\81\93ã\81®æ©\9fè\83½ã\81¯æ\96°ã\81\97ã\81\8fã\80\81å\8f¤ã\81\84ã\82µã\83¼ã\83\90ã\83¼ã\81§ã\81¯ä½¿ç\94¨ã\81§ã\81\8dã\81ªã\81\84å\8f¯è\83½æ\80§ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82\n"
 "このオプションを使用すると特定のノードタイプに適用できます。ただし、\n"
 "これは実験的なものであり、正しく機能しない可能性があります。"
 
@@ -6721,7 +6830,7 @@ msgid "The URL for the content repository"
 msgstr "コンテンツリポジトリのURL"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "ジョイスティックのデッドゾーン"
 
 #: src/settings_translation_file.cpp
@@ -6765,7 +6874,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "The network interface that the server listens on."
-msgstr "サーバが待機しているネットワークインターフェース。"
+msgstr "サーバが待機しているネットワークインターフェース。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6773,7 +6882,7 @@ msgid ""
 "See /privs in game for a full list on your server and mod configuration."
 msgstr ""
 "新規ユーザーが自動的に取得する特権。\n"
-"サーバとModの構成の完全なリストについては、ゲーム内の /privs を参照\n"
+"ã\82µã\83¼ã\83\90ã\83¼ã\81¨Modã\81®æ§\8bæ\88\90ã\81®å®\8cå\85¨ã\81ªã\83ªã\82¹ã\83\88ã\81«ã\81¤ã\81\84ã\81¦ã\81¯ã\80\81ã\82²ã\83¼ã\83 å\86\85ã\81® /privs ã\82\92å\8f\82ç\85§\n"
 "してください。"
 
 #: src/settings_translation_file.cpp
@@ -6793,7 +6902,6 @@ msgstr ""
 "これは active_object_send_range_blocks と一緒に設定する必要があります。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6802,17 +6910,18 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Irrlichtのレンダリングバックエンド。\n"
+"レンダリングのバックエンドです。\n"
 "変更後は再起動が必要です。\n"
-"注意:Android の場合、よくわからない場合は OGLES1 を使用してください!\n"
-"そうしないとアプリの起動に失敗することがあります。\n"
-"その他のプラットフォームでは、OpenGL が推奨されています。\n"
-"シェーダーは OpenGL(デスクトップのみ)と OGLES2(実験的)でサポート"
+"注:Androidでは、不明な場合はOGRES1を使用してください!そうしないとアプリの起"
+"動に失敗することがあります。\n"
+"その他のプラットフォームでは、OpenGLを推奨します。\n"
+"シェーダーは、OpenGL(デスクトップのみ)とOGRES2(実験的)でサポートされてい"
+"ます。"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr "ゲーム内の視錐台を動かすためのジョイスティック軸の感度。"
 
 #: src/settings_translation_file.cpp
@@ -6923,6 +7032,10 @@ msgstr "ツールチップの遅延"
 msgid "Touch screen threshold"
 msgstr "タッチスクリーンのしきい値"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "パフォーマンスのためのトレードオフ"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "木のノイズ"
@@ -6947,7 +7060,7 @@ msgstr "信頼するMod"
 
 #: src/settings_translation_file.cpp
 msgid "URL to the server list displayed in the Multiplayer Tab."
-msgstr "ゲームに参加タブで表示されるサーバ一覧へのURL。"
+msgstr "ゲームに参加タブで表示されるサーバ一覧へのURL。"
 
 #: src/settings_translation_file.cpp
 msgid "Undersampling"
@@ -6972,7 +7085,7 @@ msgstr "無制限のプレーヤー転送距離"
 
 #: src/settings_translation_file.cpp
 msgid "Unload unused server data"
-msgstr "æ\9cªä½¿ç\94¨ã\81®ã\82µã\83¼ã\83\90ã\83\87ã\83¼ã\82¿ã\82\92ã\82¢ã\83³ã\83­ã\83¼ã\83\89"
+msgstr "æ\9cªä½¿ç\94¨ã\81®ã\82µã\83¼ã\83\90ã\83¼ã\83\87ã\83¼ã\82¿ã\82\92ç ´æ£\84"
 
 #: src/settings_translation_file.cpp
 msgid "Upper Y limit of dungeons."
@@ -7000,14 +7113,13 @@ msgstr "テクスチャを拡大縮小する場合はバイリニアフィルタ
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
 "ミップマッピングを使用してテクスチャを拡大縮小します。特に高解像度の\n"
 "テクスチャパックを使用する場合は、パフォーマンスがわずかに向上する\n"
-"可能性があります。\n"
-"ガンマ補正縮小はサポートされていません。"
+"可能性があります。ガンマ補正縮小はサポートされていません。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7129,9 +7241,8 @@ msgid "Viewing range"
 msgstr "視野"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "バーチャルパッドでauxボタン動作"
+msgstr "バーチャルパッドで Aux1 ボタン動作"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7207,6 +7318,10 @@ msgstr "揺れる液体の波長"
 msgid "Waving plants"
 msgstr "揺れる草花"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "ウェブリンクの色"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7231,45 +7346,34 @@ msgstr ""
 "ビデオドライバのときは、古い拡大縮小方法に戻ります。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
 msgstr ""
 "バイリニア/トライリニア/異方性フィルタを使用すると、低解像度の\n"
 "テクスチャがぼやける可能性があるため、鮮明なピクセルを保持するために\n"
-"最近傍補間を使用して自動的にそれらを拡大します。\n"
-"これは拡大されたテクスチャのための最小テクスチャサイズを設定します。\n"
-"より高い値はよりシャープに見えますが、より多くのメモリを必要とします。\n"
-"2のべき乗が推奨されます。これを1より高く設定すると、\n"
-"バイリニア/トライリニア/異方性フィルタリングが有効になっていない限り、\n"
-"目に見える効果がない場合があります。\n"
+"最近傍補間を使用して自動的にそれらを拡大します。これは拡大されたテクスチャ"
+"の\n"
+"ための最小テクスチャサイズを設定します。より高い値はよりシャープに見えます"
+"が、\n"
+"より多くのメモリを必要とします。2の累乗が推奨されます。この設定は、\n"
+"バイリニア/トライリニア/異方性フィルタリングが有効の場合にのみ適用されま"
+"す。\n"
 "これは整列テクスチャの自動スケーリング用の基準ノードテクスチャサイズと\n"
 "しても使用されます。"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"フリータイプフォントを使用するかどうかは、フリータイプをサポートして\n"
-"コンパイルされている必要があります。 \n"
-"無効にした場合、代わりにビットマップおよび XML ベクターフォントが使用されま"
-"す。"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
-"既定でネームタグの背景を表示するかどうかです。\n"
+"ネームタグの背景を既定で表示するかどうかです。\n"
 "Modで背景を設定することもできます。"
 
 #: src/settings_translation_file.cpp
@@ -7297,7 +7401,7 @@ msgid ""
 msgstr ""
 "(Luaが)クラッシュした際にクライアントに再接続を要求するかどうかの\n"
 "設定です。\n"
-"サーバが自動で再起動されるように設定されているならば true に設定\n"
+"ã\82µã\83¼ã\83\90ã\83¼ã\81\8cè\87ªå\8b\95ã\81§å\86\8dèµ·å\8b\95ã\81\95ã\82\8cã\82\8bã\82\88ã\81\86ã\81«è¨­å®\9aã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\81ªã\82\89ã\81° true ã\81«è¨­å®\9a\n"
 "してください。"
 
 #: src/settings_translation_file.cpp
@@ -7324,9 +7428,8 @@ msgstr ""
 "(F5を押すのと同じ効果)。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "ウィンドウ幅の初期値。"
+msgstr "初期ウィンドウサイズの幅。フルスクリーンモードでは無視されます。"
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7427,47 +7530,24 @@ msgstr "低い地形と海底のYレベル。"
 msgid "Y-level of seabed."
 msgstr "海底のYレベル。"
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"マップブロックをディスクに保存するときに使用する ZLib圧縮レベル。\n"
-"-1 - Zlib の規定の圧縮レベル\n"
-"0 - 圧縮なし、最速\n"
-"9 - 最高の圧縮、最も遅い\n"
-"(レベル 1〜3 はZlibの「高速」方式を使用し、4〜9 は通常方式を使用)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"マップブロックをクライアントに送信するときに使用する ZLib圧縮レベル。\n"
-"-1 - Zlib の規定の圧縮レベル\n"
-"0 - 圧縮なし、最速\n"
-"9 - 最高の圧縮、最も遅い\n"
-"(レベル 1〜3 はZlibの「高速」方式を使用し、4〜9 は通常方式を使用)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURLファイルダウンロードタイムアウト"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURLタイムアウト"
+msgstr "cURL インタラクティブタイムアウト"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "cURL並行処理制限"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- クリエイティブモード: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- ダメージ: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7643,6 +7723,9 @@ msgstr "cURL並行処理制限"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "フォールバックフォントのフォント サイズ (pt)。"
 
+#~ msgid "FreeType fonts"
+#~ msgstr "フリータイプフォント"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "フルスクリーンのBPP"
 
@@ -7661,6 +7744,9 @@ msgstr "cURL並行処理制限"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 サポート。"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "インストール: ファイル: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "溶岩の深さ"
 
@@ -7763,6 +7849,17 @@ msgstr "cURL並行処理制限"
 #~ msgid "Select Package File:"
 #~ msgstr "パッケージファイルを選択:"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "影の更新時間を設定します。\n"
+#~ "値が小さいほど影やマップの更新が速くなりますが、リソースを多く消費しま"
+#~ "す。\n"
+#~ "最小値0.001秒、最大値0.2秒"
+
 #~ msgid "Shadow limit"
 #~ msgstr "影の制限"
 
@@ -7791,6 +7888,10 @@ msgstr "cURL並行処理制限"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "このフォントは特定の言語で使用されます。"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr ""
+#~ "シェーダーを有効にするにはOpenGLのドライバを使用する必要があります。"
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "映画風モード切替"
 
@@ -7810,6 +7911,16 @@ msgstr "cURL並行処理制限"
 #~ msgid "Waving water"
 #~ msgstr "揺れる水"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "フリータイプフォントを使用するかどうかは、フリータイプをサポートして\n"
+#~ "コンパイルされている必要があります。 \n"
+#~ "無効にした場合、代わりにビットマップおよび XML ベクターフォントが使用され"
+#~ "ます。"
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "ダンジョンが時折地形から突出するかどうか。"
 
@@ -7825,5 +7936,8 @@ msgstr "cURL並行処理制限"
 #~ msgid "Yes"
 #~ msgstr "はい"
 
+#~ msgid "You died."
+#~ msgstr "あなたは死にました。"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index 1f6cc89aa4438ef1697044bf8387d2d91e8f6a2a..b9e52297e7ae0273c8e1f74af04ec21cef0f1000 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Lojban (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-02-13 08:50+0000\n"
 "Last-Translator: Wuzzy <almikes@aol.com>\n"
 "Language-Team: Lojban <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -63,11 +63,6 @@ msgstr "tolcanci"
 msgid "You died"
 msgstr ".i do morsi"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr ".i do morsi"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -99,6 +94,10 @@ msgstr ""
 msgid "OK"
 msgstr "fitytu'i"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 #, fuzzy
 msgid "An error occurred in a Lua script:"
@@ -310,6 +309,10 @@ msgstr "samtcise'a"
 msgid "Install missing dependencies"
 msgstr "na'e se nitcu"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -642,7 +645,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -754,14 +757,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1145,10 +1140,6 @@ msgstr "lo xutla se gusni"
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 #, fuzzy
 msgid "Tone Mapping"
@@ -1185,7 +1176,7 @@ msgstr ".i ca'o samymo'i lo me la'o gy.node.gy."
 msgid "Waving Plants"
 msgstr "lo melbi pezli"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1219,7 +1210,8 @@ msgstr ""
 "toi"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr ""
 ".i na cumki fa le nu le se kelci cu jai se facki je cu se samymo'i .i ky. du "
 "la'o zoi."
@@ -1264,14 +1256,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- judri: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- finti se kelci: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1294,6 +1278,16 @@ msgstr "- kakne le ka simxu le ka xrani: "
 msgid "- Server Name: "
 msgstr "- cmene le samtcise'u: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr ".i da nabmi"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Automatic forward disabled"
@@ -1304,6 +1298,22 @@ msgstr "za'i ca'u muvdu"
 msgid "Automatic forward enabled"
 msgstr "za'i ca'u muvdu"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1312,6 +1322,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "basti fi le ka lerpoijaspu"
@@ -1326,6 +1340,11 @@ msgstr "le nu finti kelci"
 msgid "Cinematic mode enabled"
 msgstr "le nu finti kelci"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "lo samtciselse'u"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1334,6 +1353,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ".i ca'o samjo'e le samse'u"
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "ranji"
@@ -1357,6 +1380,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ".i ca'o cupra le samtciselse'u"
@@ -1557,6 +1585,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "lo ni sance "
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1897,6 +1940,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr ".i da nabmi fi le nu kibycpa la'o zoi. $1 .zoi"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ".i lu'i le re lerpoijaspu na simxu le ka mintu"
@@ -2107,8 +2159,8 @@ msgid "Muted"
 msgstr "ko da'ergau le batke"
 
 #: src/gui/guiVolumeChange.cpp
-#, fuzzy
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "lo ni sance "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2316,6 +2368,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2586,6 +2642,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "minde"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2621,8 +2682,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Chatcommands"
-msgstr "minde"
+msgid "Chat weblinks"
+msgstr ".i ca viska le tavla .uidje"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2642,6 +2703,12 @@ msgstr "le nu finti kelci"
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "lo samtciselse'u"
@@ -2722,6 +2789,22 @@ msgstr ""
 msgid "Command key"
 msgstr "minde"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Connect glass"
@@ -2816,7 +2899,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2893,8 +2976,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3014,6 +3097,10 @@ msgstr "lo kantu"
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3060,7 +3147,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3088,13 +3182,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3179,6 +3266,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3364,11 +3457,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3377,6 +3474,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3437,10 +3545,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3489,7 +3593,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3921,7 +4025,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4006,7 +4110,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4838,7 +4942,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5131,7 +5235,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5142,6 +5246,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5264,7 +5372,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5288,11 +5396,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5315,17 +5425,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5431,9 +5537,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5730,26 +5836,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5840,7 +5938,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5948,6 +6046,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6058,7 +6164,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6076,7 +6182,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6145,7 +6251,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6238,6 +6344,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6309,7 +6419,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6498,6 +6608,10 @@ msgstr "lo melbi pezli"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6519,7 +6633,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6527,14 +6641,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6661,24 +6768,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6691,6 +6780,9 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- finti se kelci: "
+
 #~ msgid "Address / Port"
 #~ msgstr "lo samjudri jo'u judrnporte"
 
@@ -6749,5 +6841,9 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "go'i"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr ".i do morsi"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 5046311048977d6fe38c5c4a19b1e6e4042c4734..679dc40785dcf0af7cfc56e79c7f51d867b9fd18 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Kazakh (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2020-09-09 01:23+0000\n"
 "Last-Translator: Fontan 030 <pomanfedurin@gmail.com>\n"
 "Language-Team: Kazakh <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -61,10 +61,6 @@ msgstr ""
 msgid "You died"
 msgstr ""
 
-#: builtin/client/death_formspec.lua
-msgid "You died."
-msgstr ""
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -94,6 +90,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua скриптінде қате кездесті:"
@@ -294,6 +294,10 @@ msgstr "Жою"
 msgid "Install missing dependencies"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -620,7 +624,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -730,14 +734,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1102,10 +1098,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr "Текстурлеу:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1138,7 +1130,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1167,7 +1159,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1208,14 +1200,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1237,6 +1221,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Қате кездесті:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1245,6 +1239,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1253,6 +1263,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Құпия сөзді өзгерту"
@@ -1265,6 +1279,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1273,6 +1291,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Жалғастыру"
@@ -1296,6 +1318,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1489,6 +1516,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1823,6 +1865,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2018,7 +2068,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2225,6 +2276,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2491,6 +2546,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Чат көрсетілді"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2524,8 +2584,9 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Чат көрсетілді"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2543,6 +2604,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2618,6 +2685,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2709,7 +2792,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2786,8 +2869,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2905,6 +2988,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2951,7 +3038,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2979,13 +3073,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3070,6 +3157,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3254,11 +3347,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3267,6 +3364,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3326,10 +3434,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "FreeType қаріптері"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3378,7 +3482,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3810,7 +3914,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3894,7 +3998,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4723,7 +4827,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5016,7 +5120,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5027,6 +5131,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5148,7 +5256,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5172,11 +5280,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5199,17 +5309,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5312,9 +5418,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5607,26 +5713,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5717,7 +5815,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5822,6 +5920,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5932,7 +6038,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5950,7 +6056,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6019,7 +6125,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6112,6 +6218,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6182,7 +6292,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6365,6 +6475,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6386,7 +6500,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6394,14 +6508,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6527,24 +6634,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6557,6 +6646,9 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType қаріптері"
+
 #~ msgid "Main"
 #~ msgstr "Басты мәзір"
 
index 05a910c6844c7b29aaeaa3f19f04f251bc064beb..1bba13a11f24182a87a5f7d1acb4090d4eec3a3f 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Kannada (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-01-02 07:29+0000\n"
 "Last-Translator: Tejaswi Hegde <tejaswihegde1@gmail.com>\n"
 "Language-Team: Kannada <https://hosted.weblate.org/projects/minetest/"
@@ -59,11 +59,6 @@ msgstr "ಮತ್ತೆ ಹುಟ್ಟು"
 msgid "You died"
 msgstr "ನೀನು ಸತ್ತುಹೋದೆ"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "ನೀನು ಸತ್ತುಹೋದೆ"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -93,6 +88,10 @@ msgstr ""
 msgid "OK"
 msgstr "ಸರಿ"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "ಒಂದು ಲುವಾ ಸ್ಕ್ರಿಪ್ಟ್ ನಲ್ಲಿ ತಪ್ಪಾಗಿದೆ:"
@@ -296,6 +295,10 @@ msgstr "ಇನ್ಸ್ಟಾಲ್"
 msgid "Install missing dependencies"
 msgstr "ಐಚ್ಛಿಕ ಅವಲಂಬನೆಗಳು:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -638,7 +641,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -748,14 +751,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1121,10 +1116,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1157,7 +1148,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1186,7 +1177,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1227,14 +1218,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1256,6 +1239,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "ದೋಷ ವೊಂದು ಸಂಭವಿಸಿದೆ:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1264,6 +1257,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1272,6 +1281,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1284,6 +1297,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1292,6 +1309,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1315,6 +1336,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1507,6 +1533,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1841,6 +1882,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "$1 ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಆಗಿಲ್ಲ"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2036,7 +2086,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2243,6 +2294,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2509,6 +2564,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2542,7 +2601,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2561,6 +2620,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2636,6 +2701,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2727,7 +2808,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2804,8 +2885,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2923,6 +3004,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2969,7 +3054,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2997,13 +3089,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3088,6 +3173,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3272,11 +3363,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3285,6 +3380,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3344,10 +3450,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3396,7 +3498,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3828,7 +3930,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3912,7 +4014,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4741,7 +4843,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5034,7 +5136,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5045,6 +5147,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5166,7 +5272,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5190,11 +5296,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5217,17 +5325,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5330,9 +5434,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5625,26 +5729,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5735,7 +5831,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5840,6 +5936,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5950,7 +6054,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5968,7 +6072,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6037,7 +6141,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6130,6 +6234,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6200,7 +6308,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6383,6 +6491,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6404,7 +6516,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6412,14 +6524,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6545,24 +6650,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6588,5 +6675,9 @@ msgstr ""
 #~ msgid "View"
 #~ msgstr "ತೋರಿಸು"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "ನೀನು ಸತ್ತುಹೋದೆ"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index d13da4fcd7b953d06667257eeb9bbd04b482e6a7..2db18a1790fa4b1e9d583c43ae1823adb605d7c8 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Korean (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2020-12-05 15:29+0000\n"
 "Last-Translator: HunSeongPark <gnstjd980831@naver.com>\n"
 "Language-Team: Korean <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -63,11 +63,6 @@ msgstr "리스폰"
 msgid "You died"
 msgstr "사망했습니다"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "사망했습니다"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -99,6 +94,10 @@ msgstr ""
 msgid "OK"
 msgstr "확인"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua 스크립트에서 오류가 발생했습니다:"
@@ -304,6 +303,13 @@ msgstr "설치"
 msgid "Install missing dependencies"
 msgstr "종속성 선택:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"모드 설치: \"$1\"는(은) 지원 되지 않는 파일 형식 이거나 손상된 압축 파일입니"
+"다"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -633,7 +639,8 @@ msgid "Offset"
 msgstr "오프셋"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "플레이어 전송 거리"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -743,16 +750,6 @@ msgstr "모드 설치: $1를(을) 찾을 수 없습니다"
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "모드 설치: 모드 팩 $1 (이)의 올바른 폴더이름을 찾을 수 없습니다"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"모드 설치: \"$1\"는(은) 지원 되지 않는 파일 형식 이거나 손상된 압축 파일입니"
-"다"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "모드 설치: 파일: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "설치 모드: 모드 팩 $1 (이)의 올바른 폴더이름을 찾을 수 없습니다"
@@ -1128,10 +1125,6 @@ msgstr "부드러운 조명 효과"
 msgid "Texturing:"
 msgstr "질감:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "쉐이더를 사용하려면 OpenGL 드라이버를 사용할 필요가 있습니다."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "톤 매핑"
@@ -1164,7 +1157,7 @@ msgstr "물 등의 물결효과"
 msgid "Waving Plants"
 msgstr "움직이는 식물 효과"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "연결 시간이 초과했습니다."
 
@@ -1193,7 +1186,8 @@ msgid "Connection error (timed out?)"
 msgstr "연결 오류 (시간초과)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "게임을 찾지 못했거나 로딩할 수 없습니다\""
 
 #: src/client/clientlauncher.cpp
@@ -1236,14 +1230,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- 주소: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- 크리에이티브 모드: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- 데미지: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- 모드: "
@@ -1265,6 +1251,16 @@ msgstr "- Player vs Player: "
 msgid "- Server Name: "
 msgstr "- 서버 이름: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "오류가 발생했습니다:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "자동 전진 비활성화"
@@ -1273,6 +1269,22 @@ msgstr "자동 전진 비활성화"
 msgid "Automatic forward enabled"
 msgstr "자동 전진 활성화"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "카메라 업데이트 비활성화"
@@ -1281,6 +1293,10 @@ msgstr "카메라 업데이트 비활성화"
 msgid "Camera update enabled"
 msgstr "카메라 업데이트 활성화"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "비밀번호 변경"
@@ -1293,6 +1309,11 @@ msgstr "시네마틱 모드 비활성화"
 msgid "Cinematic mode enabled"
 msgstr "시네마틱 모드 활성화"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "클라이언트 모딩"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "클라이언트 스크립트가 비활성화됨"
@@ -1301,6 +1322,10 @@ msgstr "클라이언트 스크립트가 비활성화됨"
 msgid "Connecting to server..."
 msgstr "서버 연결중..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "계속"
@@ -1338,6 +1363,11 @@ msgstr ""
 "-마우스 휠:아이템 선택\n"
 "-%s: 채팅\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "클라이언트 만드는 중..."
@@ -1543,6 +1573,21 @@ msgstr "본 빌드에서 지원되지 않는 사운드 시스템"
 msgid "Sound unmuted"
 msgstr "음소거 해제"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1878,6 +1923,15 @@ msgstr "표면 모드의 미니맵, 1배 확대"
 msgid "Minimap in texture mode"
 msgstr "최소 텍스처 크기"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "$1을 다운로드하는 데에 실패했습니다"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "비밀번호가 맞지 않습니다!"
@@ -2079,7 +2133,8 @@ msgid "Muted"
 msgstr "음소거"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "볼륨 조절: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2330,6 +2385,10 @@ msgid ""
 msgstr ""
 "화면에 맞게 dpi 구성을 조정합니다 (X11 미지원 / Android 만 해당). 4k 화면 용."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2626,6 +2685,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "채팅 메세지 강제퇴장 임계값"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "채팅 명렁어"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "채팅 글자 크기"
@@ -2659,8 +2723,9 @@ msgid "Chat toggle key"
 msgstr "채팅 스위치"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "채팅 명렁어"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "채팅 보이기"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2678,6 +2743,12 @@ msgstr "시네마틱 모드 스위치"
 msgid "Clean transparent textures"
 msgstr "깨끗하고 투명한 텍스처"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "클라이언트"
@@ -2766,6 +2837,22 @@ msgstr ""
 msgid "Command key"
 msgstr "명령 키"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "유리를 연결"
@@ -2866,7 +2953,7 @@ msgstr "십자선 투명도"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr "십자선 투명도 (불투명 함, 0과 255 사이)."
 
 #: src/settings_translation_file.cpp
@@ -2945,8 +3032,8 @@ msgstr "기본 스택 크기"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3065,6 +3152,10 @@ msgstr "Anticheat를 사용 안함"
 msgid "Disallow empty passwords"
 msgstr "비밀번호 없으면 불가"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "도메인 서버의 이름은 서버리스트에 표시 됩니다."
@@ -3111,7 +3202,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3140,13 +3238,6 @@ msgstr "모드 보안 적용"
 msgid "Enable players getting damage and dying."
 msgstr "플레이어는 데미지를 받고 죽을 수 있습니다."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "랜덤 사용자 입력 (테스트에 사용)를 사용 합니다."
@@ -3243,6 +3334,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "엔진 프로 파일링 데이터 출력 간격"
@@ -3433,11 +3530,15 @@ msgid "Font size"
 msgstr "글꼴 크기"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3446,6 +3547,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3505,10 +3617,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Freetype 글꼴"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3557,7 +3665,7 @@ msgstr "글로벌 콜백"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3995,7 +4103,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4079,7 +4187,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5132,7 +5240,7 @@ msgid "Map save interval"
 msgstr "맵 저장 간격"
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5431,7 +5539,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5442,6 +5550,11 @@ msgstr "고정 폭 글꼴 경로"
 msgid "Monospace font size"
 msgstr "고정 폭 글꼴 크기"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "고정 폭 글꼴 크기"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5568,7 +5681,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5592,11 +5705,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5620,17 +5735,13 @@ msgstr "텍스처 디렉터리 경로입니다. 모든 텍스처는 여기에서
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5742,9 +5853,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6063,26 +6174,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6191,7 +6294,7 @@ msgstr ""
 "설정 적용 후 재시작이 필요합니다."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6302,6 +6405,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6412,7 +6523,7 @@ msgstr "텍스처 경로"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6430,7 +6541,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6502,7 +6613,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6601,6 +6712,10 @@ msgstr "도구 설명 지연"
 msgid "Touch screen threshold"
 msgstr "터치임계값 (픽셀)"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6674,7 +6789,7 @@ msgstr "이중 선형 필터링은 질감 스케일링을 할 때 사용 합니
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6859,6 +6974,11 @@ msgstr "물결 길이"
 msgid "Waving plants"
 msgstr "흔들리는 식물 효과"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "선택 박스 컬러"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6885,7 +7005,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6903,14 +7023,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7041,24 +7154,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -7071,6 +7166,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- 크리에이티브 모드: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- 데미지: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7187,6 +7288,9 @@ msgstr ""
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "글꼴 그림자 투명도 (불투명 함, 0과 255 사이)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Freetype 글꼴"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "전체 화면 BPP"
 
@@ -7199,6 +7303,9 @@ msgstr ""
 #~ msgid "Generate normalmaps"
 #~ msgstr "Normalmaps 생성"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "모드 설치: 파일: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "큰 동굴 깊이"
@@ -7309,6 +7416,9 @@ msgstr ""
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "이 글꼴은 특정 언어에 사용 됩니다."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "쉐이더를 사용하려면 OpenGL 드라이버를 사용할 필요가 있습니다."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "시네마틱 스위치"
 
@@ -7324,5 +7434,9 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "예"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "사망했습니다"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index 504e878e134d3de348f6e0d05e95c504449785ce..ca0910781a1d0888cd769d39e3a0964ec8f4e384 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Kyrgyz (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2019-11-10 15:04+0000\n"
 "Last-Translator: Krock <mk939@ymail.com>\n"
 "Language-Team: Kyrgyz <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -64,11 +64,6 @@ msgstr "Кайтадан жаралуу"
 msgid "You died"
 msgstr "Сиз өлдүңүз."
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Сиз өлдүңүз."
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -100,6 +95,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr ""
@@ -313,6 +312,10 @@ msgstr ""
 msgid "Install missing dependencies"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -642,7 +645,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -757,14 +760,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1163,10 +1158,6 @@ msgstr "Тегиз жарык"
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 #, fuzzy
 msgid "Tone Mapping"
@@ -1204,7 +1195,7 @@ msgstr "Кооз бактар"
 msgid "Waving Plants"
 msgstr "Кооз бактар"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 #, fuzzy
 msgid "Connection timed out."
 msgstr "Туташтыруу катасы (убактыңыз өтүп кеттиби?)"
@@ -1236,7 +1227,8 @@ msgid "Connection error (timed out?)"
 msgstr "Туташтыруу катасы (убактыңыз өтүп кеттиби?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Оюнду табуу же жүктөө мүмкүн эмес \""
 
 #: src/client/clientlauncher.cpp
@@ -1280,16 +1272,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "Дареги/порту"
 
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Creative Mode: "
-msgstr "Жаратуу режими"
-
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Damage: "
-msgstr "Убалды күйгүзүү"
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1312,6 +1294,15 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Automatic forward disabled"
@@ -1322,6 +1313,22 @@ msgstr "Алга"
 msgid "Automatic forward enabled"
 msgstr "Алга"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1331,6 +1338,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr "күйгүзүлгөн"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Сырсөздү өзгөртүү"
@@ -1345,6 +1356,10 @@ msgstr "Жаратуу режими"
 msgid "Cinematic mode enabled"
 msgstr "Жаратуу режими"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1353,6 +1368,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr "Серверге туташтырылууда..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Улантуу"
@@ -1387,6 +1406,11 @@ msgstr ""
 "- Чычкан дөңгөлөгү: буюмду тандоо\n"
 "- T: маек\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Клиент жаратылууда..."
@@ -1594,6 +1618,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Үн көлөмү"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1934,6 +1973,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Дүйнөнү инициалдаштыруу катасы"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Сырсөздөр дал келген жок!"
@@ -2141,7 +2189,8 @@ msgid "Muted"
 msgstr "баскычты басыңыз"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Үн көлөмү: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2349,6 +2398,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2622,6 +2675,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Команда"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2658,9 +2716,8 @@ msgid "Chat toggle key"
 msgstr "Баскычтарды өзгөртүү"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Chatcommands"
-msgstr "Команда"
+msgid "Chat weblinks"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2680,6 +2737,12 @@ msgstr "Жаратуу режими"
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2758,6 +2821,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Команда"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Connect glass"
@@ -2857,7 +2936,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2936,8 +3015,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3058,6 +3137,10 @@ msgstr "Бөлүкчөлөрдү күйгүзүү"
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3104,7 +3187,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3132,13 +3222,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3224,6 +3307,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3409,11 +3498,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3422,6 +3515,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3482,10 +3586,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3534,7 +3634,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3969,7 +4069,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4054,7 +4154,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4887,7 +4987,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5182,7 +5282,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5193,6 +5293,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5315,7 +5419,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5339,11 +5443,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5366,17 +5472,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5482,9 +5584,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5786,26 +5888,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5898,7 +5992,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6006,6 +6100,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6116,7 +6218,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6134,7 +6236,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6203,7 +6305,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6296,6 +6398,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6367,7 +6473,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6556,6 +6662,10 @@ msgstr "Кооз бактар"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6577,7 +6687,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6585,14 +6695,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6719,24 +6822,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6749,6 +6834,14 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#, fuzzy
+#~ msgid "- Creative Mode: "
+#~ msgstr "Жаратуу режими"
+
+#, fuzzy
+#~ msgid "- Damage: "
+#~ msgstr "Убалды күйгүзүү"
+
 #, fuzzy
 #~ msgid "Address / Port"
 #~ msgstr "Дареги/порту"
@@ -6835,5 +6928,9 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "Ооба"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Сиз өлдүңүз."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index d16babb11ebbf09414ba5aad4cff15ed2e3f3a7e..20c24fd0bae660dc455103d385cb9d24af961f23 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Lithuanian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-04-10 15:49+0000\n"
 "Last-Translator: Kornelijus Tvarijanavičius <kornelitvari@protonmail.com>\n"
 "Language-Team: Lithuanian <https://hosted.weblate.org/projects/minetest/"
@@ -64,11 +64,6 @@ msgstr "Prisikelti"
 msgid "You died"
 msgstr "Jūs numirėte"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Jūs numirėte"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -100,6 +95,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Įvyko klaida Lua skripte:"
@@ -302,6 +301,12 @@ msgstr "Įdiegti"
 msgid "Install missing dependencies"
 msgstr "Inicijuojami mazgai"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"Papildinio diegimas: nepalaikomas failo tipas „$1“ arba sugadintas archyvas"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -640,7 +645,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -757,16 +762,6 @@ msgstr ""
 "Papildinio diegimas: nepavyksta rasti tinkamo aplanko pavadinimo papildinio "
 "paketui $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Papildinio diegimas: nepalaikomas failo tipas „$1“ arba sugadintas archyvas"
-
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: file: \"$1\""
-msgstr "Įdiegti papildinį: failas: „$1“"
-
 #: builtin/mainmenu/pkgmgr.lua
 #, fuzzy
 msgid "Unable to find a valid mod or modpack"
@@ -1166,10 +1161,6 @@ msgstr "Apšvietimo efektai"
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1204,7 +1195,7 @@ msgstr "Nepermatomi lapai"
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Baigėsi prijungimo laikas."
 
@@ -1233,7 +1224,8 @@ msgid "Connection error (timed out?)"
 msgstr "Ryšio klaida (baigėsi prijungimo laikas?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Nepavyko rasti ar įkelti žaidimo „"
 
 #: src/client/clientlauncher.cpp
@@ -1277,14 +1269,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresas: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kūrybinis režimas "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Sužeidimai: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1306,6 +1290,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr "- Serverio pavadinimas: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Įvyko klaida:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Automatic forward disabled"
@@ -1316,6 +1310,22 @@ msgstr "Pirmyn"
 msgid "Automatic forward enabled"
 msgstr "Pirmyn"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1325,6 +1335,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr "Žalojimas įjungtas"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Keisti slaptažodį"
@@ -1339,6 +1353,11 @@ msgstr "Kūrybinė veiksena"
 msgid "Cinematic mode enabled"
 msgstr "Kūrybinė veiksena"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Žaisti tinkle(klientas)"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1347,6 +1366,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr "Jungiamasi prie serverio..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Tęsti"
@@ -1384,6 +1407,11 @@ msgstr ""
 "- Pelės ratukas: pasirinkti elementą\n"
 "- %s: kalbėtis\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Kuriamas klientas..."
@@ -1599,6 +1627,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Garso lygis"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1941,6 +1984,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Nepavyko parsiųsti $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Slaptažodžiai nesutampa!"
@@ -2148,7 +2200,8 @@ msgid "Muted"
 msgstr "paspauskite klavišą"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Garso lygis: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2356,6 +2409,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2626,6 +2683,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Komanda"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2662,9 +2724,8 @@ msgid "Chat toggle key"
 msgstr "Nustatyti klavišus"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Chatcommands"
-msgstr "Komanda"
+msgid "Chat weblinks"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2684,6 +2745,12 @@ msgstr "Kūrybinė veiksena"
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Žaisti tinkle(klientas)"
@@ -2764,6 +2831,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Komanda"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Connect glass"
@@ -2860,7 +2943,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2941,8 +3024,8 @@ msgstr "keisti žaidimą"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3062,6 +3145,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3108,7 +3195,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3137,13 +3231,6 @@ msgstr "Papildiniai internete"
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3228,6 +3315,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3412,11 +3505,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3425,6 +3522,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3485,10 +3593,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3537,7 +3641,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3973,7 +4077,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4058,7 +4162,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4891,7 +4995,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5194,7 +5298,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5205,6 +5309,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5327,7 +5435,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5351,11 +5459,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5378,17 +5488,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5493,9 +5599,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5798,26 +5904,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5909,7 +6007,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6017,6 +6115,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6127,7 +6233,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6145,7 +6251,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6214,7 +6320,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6307,6 +6413,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6377,7 +6487,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6564,6 +6674,10 @@ msgstr "Nepermatomi lapai"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6585,7 +6699,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6593,14 +6707,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6727,24 +6834,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6757,6 +6846,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kūrybinis režimas "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Sužeidimai: "
+
 #~ msgid "Address / Port"
 #~ msgstr "Adresas / Prievadas"
 
@@ -6790,6 +6885,10 @@ msgstr ""
 #~ msgid "Enables filmic tone mapping"
 #~ msgstr "Leisti sužeidimus"
 
+#, fuzzy
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Įdiegti papildinį: failas: „$1“"
+
 #~ msgid "Main"
 #~ msgstr "Pagrindinis"
 
@@ -6840,5 +6939,9 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "Taip"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Jūs numirėte"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index cf8a5f4f39f3a2da5a4e2e28db92a9cb90bc3771..24fc8faeb8dfa2f71a203e3434114a93cc644887 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-04-02 10:26+0000\n"
 "Last-Translator: Dainis <dainis.skuja@gmail.com>\n"
 "Language-Team: Latvian <https://hosted.weblate.org/projects/minetest/"
@@ -68,11 +68,6 @@ msgstr "Atdzīvoties"
 msgid "You died"
 msgstr "Jūs nomirāt"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Jūs nomirāt"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -104,6 +99,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua skriptā radās kļūme:"
@@ -310,6 +309,11 @@ msgstr "Instalēt"
 msgid "Install missing dependencies"
 msgstr "Neobligātās atkarības:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Instalācija: Neatbalstīts faila tips “$1” vai arī sabojāts arhīvs"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -641,7 +645,8 @@ msgid "Offset"
 msgstr "Nobīde"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Noturība"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -753,14 +758,6 @@ msgstr ""
 "Moda instalācija: Neizdevās atrast derīgu mapes nosaukumu priekš modu "
 "komplekta “$1”"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Instalācija: Neatbalstīts faila tips “$1” vai arī sabojāts arhīvs"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instalācija: fails: “$1”"
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Neizdevās atrast derīgu modu vai modu komplektu"
@@ -1136,10 +1133,6 @@ msgstr "Gluds apgaismojums"
 msgid "Texturing:"
 msgstr "Teksturēšana:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Lai iespējotu šeiderus, jāizmanto OpenGL draiveris."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Toņu atbilstība"
@@ -1172,7 +1165,7 @@ msgstr "Viļņojoši šķidrumi"
 msgid "Waving Plants"
 msgstr "Viļņojoši augi"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Savienojuma noildze."
 
@@ -1201,7 +1194,8 @@ msgid "Connection error (timed out?)"
 msgstr "Savienojuma kļūme (noildze?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Nevarēja atrast vai ielādēt spēli \""
 
 #: src/client/clientlauncher.cpp
@@ -1244,14 +1238,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adrese: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Radošais režīms: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Bojājumi: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Režīms: "
@@ -1273,6 +1259,16 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Severa nosaukums: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Radās kļūme:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automātiskā pārvietošanās izslēgta"
@@ -1281,6 +1277,22 @@ msgstr "Automātiskā pārvietošanās izslēgta"
 msgid "Automatic forward enabled"
 msgstr "Automātiskā pārvietošanās ieslēgta"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kameras atjaunošana atspējota"
@@ -1289,6 +1301,10 @@ msgstr "Kameras atjaunošana atspējota"
 msgid "Camera update enabled"
 msgstr "Kameras atjaunošana iespējota"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Nomainīt paroli"
@@ -1301,6 +1317,10 @@ msgstr "Kino režīms izslēgts"
 msgid "Cinematic mode enabled"
 msgstr "Kino režīms ieslēgts"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Klienta puses skriptēšana ir atspējota"
@@ -1309,6 +1329,10 @@ msgstr "Klienta puses skriptēšana ir atspējota"
 msgid "Connecting to server..."
 msgstr "Savienojas ar serveri..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Turpināt"
@@ -1346,6 +1370,11 @@ msgstr ""
 "- Peles rullītis: izvēlēties priekšmetu\n"
 "- %s: čats\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Izveido klientu..."
@@ -1552,6 +1581,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Skaņa ieslēgta"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1887,6 +1931,15 @@ msgstr "Minikarte virsmas režīmā, palielinājums x1"
 msgid "Minimap in texture mode"
 msgstr "Minikarte virsmas režīmā, palielinājums x1"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Neizdevās lejuplādēt $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Paroles nesakrīt!"
@@ -2091,7 +2144,8 @@ msgid "Muted"
 msgstr "Apklusināts"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Skaņas skaļums: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2298,6 +2352,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2564,6 +2622,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Komanda"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2597,8 +2660,9 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Čats parādīts"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2616,6 +2680,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2691,6 +2761,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2782,7 +2868,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2859,8 +2945,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2978,6 +3064,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3024,7 +3114,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3052,13 +3149,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3143,6 +3233,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3330,11 +3426,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3343,6 +3443,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3402,10 +3513,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3454,7 +3561,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3890,7 +3997,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3974,7 +4081,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4803,7 +4910,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5096,7 +5203,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5107,6 +5214,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5228,7 +5339,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5252,11 +5363,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5279,17 +5392,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5394,9 +5503,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5689,26 +5798,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5799,7 +5900,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5904,6 +6005,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6014,7 +6123,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6032,7 +6141,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6101,7 +6210,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6194,6 +6303,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6264,7 +6377,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6447,6 +6560,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6468,7 +6585,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6476,14 +6593,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6609,24 +6719,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6639,6 +6731,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Radošais režīms: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Bojājumi: "
+
 #~ msgid "Address / Port"
 #~ msgstr "Adrese / Ports"
 
@@ -6671,6 +6769,9 @@ msgstr ""
 #~ msgid "Generate Normal Maps"
 #~ msgstr "Izveidot normāl-kartes"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instalācija: fails: “$1”"
+
 #~ msgid "Main"
 #~ msgstr "Galvenā izvēlne"
 
@@ -6713,8 +6814,15 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Sākt viena spēlētāja spēli"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Lai iespējotu šeiderus, jāizmanto OpenGL draiveris."
+
 #~ msgid "Yes"
 #~ msgstr "Jā"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Jūs nomirāt"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
diff --git a/po/lzh/minetest.po b/po/lzh/minetest.po
new file mode 100644 (file)
index 0000000..0b30305
--- /dev/null
@@ -0,0 +1,6641 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the minetest package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: minetest\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-20 14:35+0000\n"
+"Last-Translator: Gao Tiesuan <yepifoas@666email.com>\n"
+"Language-Team: Chinese (Literary) <https://hosted.weblate.org/projects/"
+"minetest/minetest/lzh/>\n"
+"Language: lzh\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 4.11-dev\n"
+
+#: builtin/client/chatcommands.lua
+msgid "Clear the out chat queue"
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Empty command."
+msgstr "空令。"
+
+#: builtin/client/chatcommands.lua
+msgid "Exit to main menu"
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Invalid command: "
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Issued command: "
+msgstr "令之传者: "
+
+#: builtin/client/chatcommands.lua
+msgid "List online players"
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Online players: "
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "The out chat queue is now empty."
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "This command is disabled by server."
+msgstr ""
+
+#: builtin/client/death_formspec.lua src/client/game.cpp
+msgid "Respawn"
+msgstr "复生"
+
+#: builtin/client/death_formspec.lua src/client/game.cpp
+msgid "You died"
+msgstr "尔死矣"
+
+#: builtin/common/chatcommands.lua
+msgid "Available commands:"
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "Available commands: "
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "Command not available: "
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "Get help for commands"
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid ""
+"Use '.help <cmd>' to get more information, or '.help all' to list everything."
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "[all | <cmd>]"
+msgstr ""
+
+#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
+msgid "OK"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "An error occurred in a Lua script:"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "An error occurred:"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "Main menu"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "Reconnect"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "The server has requested a reconnect:"
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "Protocol version mismatch. "
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "Server enforces protocol version $1. "
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "Server supports protocol versions between $1 and $2. "
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "We only support protocol version $1."
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "We support protocol versions between version $1 and $2."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/dlg_create_world.lua
+#: builtin/mainmenu/dlg_delete_content.lua
+#: builtin/mainmenu/dlg_delete_world.lua
+#: builtin/mainmenu/dlg_rename_modpack.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp
+#: src/gui/guiConfirmRegistration.cpp src/gui/guiKeyChangeMenu.cpp
+#: src/gui/guiPasswordChange.cpp
+msgid "Cancel"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/tab_content.lua
+msgid "Dependencies:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Disable all"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Disable modpack"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Enable all"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Enable modpack"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid ""
+"Failed to enable mod \"$1\" as it contains disallowed characters. Only "
+"characters [a-z0-9_] are allowed."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Find More Mods"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Mod:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No (optional) dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No game description provided."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No hard dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No modpack description provided."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No optional dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua
+msgid "Optional dependencies:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp
+msgid "Save"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "World:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "enabled"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "\"$1\" already exists. Would you like to overwrite it?"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 and $2 dependencies will be installed."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 by $2"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid ""
+"$1 downloading,\n"
+"$2 queued"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 downloading..."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 required dependencies could not be found."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 will be installed, and $2 dependencies will be skipped."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "All packages"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Already installed"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Back to Main Menu"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Base Game:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "ContentDB is not available when Minetest was compiled without cURL"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Downloading..."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Failed to download $1"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Games"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install $1"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install missing dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Mods"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "No packages could be retrieved"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "No results"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "No updates"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Not found"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Overwrite"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Please check that the base game is correct."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Queued"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Texture packs"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Uninstall"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Update"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Update All [$1]"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "View more information in a web browser"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "A world named \"$1\" already exists"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Additional terrain"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Altitude chill"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Altitude dry"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Biome blending"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Biomes"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Caverns"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Caves"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Create"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Decorations"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Download a game, such as Minetest Game, from minetest.net"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Download one from minetest.net"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Dungeons"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Flat terrain"
+msgstr "平地"
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Floating landmasses in the sky"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Floatlands (experimental)"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Game"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Generate non-fractal terrain: Oceans and underground"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Hills"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Humid rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Increases humidity around rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Lakes"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Low humidity and high heat causes shallow or dry rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Mapgen"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Mapgen flags"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Mapgen-specific flags"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Mountains"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Mud flow"
+msgstr "泥流"
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Network of tunnels and caves"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "No game selected"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Reduces heat with altitude"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Reduces humidity with altitude"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Rivers"
+msgstr "川"
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Sea level rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Seed"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Smooth transition between biomes"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid ""
+"Structures appearing on the terrain (no effect on trees and jungle grass "
+"created by v6)"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Structures appearing on the terrain, typically trees and plants"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Temperate, Desert"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Temperate, Desert, Jungle"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Temperate, Desert, Jungle, Tundra, Taiga"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Terrain surface erosion"
+msgstr "地表之蚀"
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Trees and jungle grass"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Vary river depth"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Very large caverns deep in the underground"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Warning: The Development Test is meant for developers."
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "World name"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "You have no games installed."
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+msgid "Are you sure you want to delete \"$1\"?"
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua
+#: src/client/keycode.cpp
+msgid "Delete"
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+msgid "pkgmgr: failed to delete \"$1\""
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+msgid "pkgmgr: invalid path \"$1\""
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_world.lua
+msgid "Delete World \"$1\"?"
+msgstr ""
+
+#: builtin/mainmenu/dlg_rename_modpack.lua
+msgid "Accept"
+msgstr ""
+
+#: builtin/mainmenu/dlg_rename_modpack.lua
+msgid "Rename Modpack:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_rename_modpack.lua
+msgid ""
+"This modpack has an explicit name given in its modpack.conf which will "
+"override any renaming here."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "(No description of setting given)"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "2D Noise"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "< Back to Settings page"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Browse"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua
+msgid "Disabled"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Edit"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Enabled"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Lacunarity"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Octaves"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
+msgid "Offset"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Persistence"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Please enter a valid integer."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Please enter a valid number."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Restore Default"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
+msgid "Scale"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua
+msgid "Search"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Select directory"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Select file"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Show technical names"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "The value must be at least $1."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "The value must not be larger than $1."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "X"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "X spread"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Y"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Y spread"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Z"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Z spread"
+msgstr ""
+
+#. ~ "absvalue" is a noise parameter flag.
+#. It is short for "absolute value".
+#. It can be enabled in noise settings in
+#. main menu -> "All Settings".
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "absvalue"
+msgstr ""
+
+#. ~ "defaults" is a noise parameter flag.
+#. It describes the default processing options
+#. for noise settings in main menu -> "All Settings".
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "defaults"
+msgstr ""
+
+#. ~ "eased" is a noise parameter flag.
+#. It is used to make the map smoother and
+#. can be enabled in noise settings in
+#. main menu -> "All Settings".
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "eased"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "$1 (Enabled)"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "$1 mods"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Failed to install $1 to $2"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Install Mod: Unable to find real mod name for: $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Install Mod: Unable to find suitable folder name for modpack $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to find a valid mod or modpack"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a $1 as a texture pack"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a game as a $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a mod as a $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a modpack as a $1"
+msgstr ""
+
+#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp
+msgid "Loading..."
+msgstr ""
+
+#: builtin/mainmenu/serverlistmgr.lua
+msgid "Public server list is disabled"
+msgstr ""
+
+#: builtin/mainmenu/serverlistmgr.lua
+msgid "Try reenabling public serverlist and check your internet connection."
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "About"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Active Contributors"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Active renderer:"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Core Developers"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Open User Data Directory"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid ""
+"Opens the directory that contains user-provided worlds, games, mods,\n"
+"and texture packs in a file manager / explorer."
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Previous Contributors"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Previous Core Developers"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Browse online content"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Content"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Disable Texture Pack"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Information:"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Installed Packages:"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "No dependencies."
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "No package description available"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Rename"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Uninstall Package"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Use Texture Pack"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Announce Server"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Bind Address"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Creative Mode"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Enable Damage"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Host Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Host Server"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Install games from ContentDB"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
+msgid "Name"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "New"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "No world created or selected!"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
+msgid "Password"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Play Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
+msgid "Port"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Select Mods"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Select World:"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Server Port"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Start Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Address"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
+msgid "Clear"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Connect"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Creative mode"
+msgstr ""
+
+#. ~ PvP = Player versus Player
+#: builtin/mainmenu/tab_online.lua
+msgid "Damage / PvP"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Del. Favorite"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Favorites"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Incompatible Servers"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Join Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Ping"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Public Servers"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Refresh"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Server Description"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "2x"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "3D Clouds"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "4x"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "8x"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "All Settings"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Antialiasing:"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Autosave Screen Size"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Bilinear Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/client/game.cpp
+msgid "Change Keys"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Connected Glass"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
+msgid "Dynamic shadows"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Dynamic shadows: "
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Fancy Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "High"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Low"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Medium"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Mipmap"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Mipmap + Aniso. Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "No Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "No Mipmap"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Node Highlighting"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Node Outlining"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "None"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Opaque Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Opaque Water"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Particles"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Screen:"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Settings"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
+msgid "Shaders"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Shaders (experimental)"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Shaders (unavailable)"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Simple Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Smooth Lighting"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Texturing:"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
+msgid "Tone Mapping"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Touchthreshold: (px)"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Trilinear Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Ultra High"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Very Low"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Waving Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Waving Liquids"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Waving Plants"
+msgstr ""
+
+#: src/client/client.cpp src/client/game.cpp
+msgid "Connection timed out."
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Done!"
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Initializing nodes"
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Initializing nodes..."
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Loading textures..."
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Rebuilding shaders..."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Connection error (timed out?)"
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Could not find or load game: "
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Invalid gamespec."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Main Menu"
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "No world selected and no address provided. Nothing to do."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Player name too long."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Please choose a name!"
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Provided password file failed to open: "
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Provided world path doesn't exist: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid ""
+"\n"
+"Check debug.txt for details."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Address: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Mode: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Port: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Public: "
+msgstr ""
+
+#. ~ PvP = Player versus Player
+#: src/client/game.cpp
+msgid "- PvP: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Server Name: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Automatic forward disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Automatic forward enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Camera update disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Camera update enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Change Password"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Cinematic mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Cinematic mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Client side scripting is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Connecting to server..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Continue"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid ""
+"Controls:\n"
+"- %s: move forwards\n"
+"- %s: move backwards\n"
+"- %s: move left\n"
+"- %s: move right\n"
+"- %s: jump/climb up\n"
+"- %s: dig/punch\n"
+"- %s: place/use\n"
+"- %s: sneak/climb down\n"
+"- %s: drop item\n"
+"- %s: inventory\n"
+"- Mouse: turn/look\n"
+"- Mouse wheel: select item\n"
+"- %s: chat\n"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Creating client..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Creating server..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Debug info and profiler graph hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Debug info shown"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Debug info, profiler graph, and wireframe hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid ""
+"Default Controls:\n"
+"No menu visible:\n"
+"- single tap: button activate\n"
+"- double tap: place/use\n"
+"- slide finger: look around\n"
+"Menu/Inventory visible:\n"
+"- double tap (outside):\n"
+" -->close\n"
+"- touch stack, touch slot:\n"
+" --> move stack\n"
+"- touch&drag, tap 2nd finger\n"
+" --> place single item to slot\n"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Disabled unlimited viewing range"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Enabled unlimited viewing range"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Exit to Menu"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Exit to OS"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fast mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fast mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fast mode enabled (note: no 'fast' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fly mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fly mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fly mode enabled (note: no 'fly' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fog disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fog enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Game info:"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Game paused"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Hosting server"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Item definitions..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "KiB/s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Media..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "MiB/s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Minimap currently disabled by game or mod"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Multiplayer"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Noclip mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Noclip mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Noclip mode enabled (note: no 'noclip' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Node definitions..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Off"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "On"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Pitch move mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Pitch move mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Profiler graph shown"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Remote server"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Resolving address..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Shutting down..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Singleplayer"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound Volume"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound muted"
+msgstr "消音"
+
+#: src/client/game.cpp
+msgid "Sound system is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound system is not supported on this build"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound unmuted"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Viewing range changed to %d"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Viewing range is at maximum: %d"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Viewing range is at minimum: %d"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Volume changed to %d%%"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Wireframe shown"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Zoom currently disabled by game or mod"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "ok"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "Chat hidden"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "Chat shown"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "HUD hidden"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "HUD shown"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "Profiler hidden"
+msgstr ""
+
+#: src/client/gameui.cpp
+#, c-format
+msgid "Profiler shown (page %d of %d)"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Apps"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Backspace"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Caps Lock"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Control"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Down"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "End"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Erase EOF"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Execute"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Help"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Home"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Accept"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Convert"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Escape"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Mode Change"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Nonconvert"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Insert"
+msgstr ""
+
+#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
+msgid "Left"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Button"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Control"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Menu"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Shift"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Windows"
+msgstr ""
+
+#. ~ Key name, common on Windows keyboards
+#: src/client/keycode.cpp
+msgid "Menu"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Middle Button"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Num Lock"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad *"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad +"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad -"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad ."
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad /"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 0"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 1"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 2"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 3"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 4"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 5"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 6"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 7"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 8"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 9"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "OEM Clear"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Page down"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Page up"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Pause"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Play"
+msgstr ""
+
+#. ~ "Print screen" key
+#: src/client/keycode.cpp
+msgid "Print"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Return"
+msgstr ""
+
+#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
+msgid "Right"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Button"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Control"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Menu"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Shift"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Windows"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Scroll Lock"
+msgstr ""
+
+#. ~ Key name
+#: src/client/keycode.cpp
+msgid "Select"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Shift"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Sleep"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Snapshot"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Space"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Tab"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Up"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "X Button 1"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "X Button 2"
+msgstr ""
+
+#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
+msgid "Zoom"
+msgstr ""
+
+#: src/client/minimap.cpp
+msgid "Minimap hidden"
+msgstr ""
+
+#: src/client/minimap.cpp
+#, c-format
+msgid "Minimap in radar mode, Zoom x%d"
+msgstr ""
+
+#: src/client/minimap.cpp
+#, c-format
+msgid "Minimap in surface mode, Zoom x%d"
+msgstr ""
+
+#: src/client/minimap.cpp
+msgid "Minimap in texture mode"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
+#: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
+msgid "Passwords do not match!"
+msgstr ""
+
+#: src/gui/guiConfirmRegistration.cpp
+msgid "Register and Join"
+msgstr ""
+
+#: src/gui/guiConfirmRegistration.cpp
+#, c-format
+msgid ""
+"You are about to join this server with the name \"%s\" for the first time.\n"
+"If you proceed, a new account using your credentials will be created on this "
+"server.\n"
+"Please retype your password and click 'Register and Join' to confirm account "
+"creation, or click 'Cancel' to abort."
+msgstr ""
+
+#: src/gui/guiFormSpecMenu.cpp
+msgid "Proceed"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "\"Aux1\" = climb down"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Autoforward"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
+msgid "Automatic jumping"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Aux1"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Backward"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Block bounds"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Change camera"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Chat"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Command"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Console"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Dec. range"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Dec. volume"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Double tap \"jump\" to toggle fly"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Drop"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Forward"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Inc. range"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Inc. volume"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Jump"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Key already in use"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Local command"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Mute"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Next item"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Prev. item"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Range select"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
+msgid "Screenshot"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Sneak"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle HUD"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle chat log"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle fast"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle fly"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle fog"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle minimap"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle noclip"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle pitchmove"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "press key"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "Change"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "Confirm Password"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "New Password"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "Old Password"
+msgstr ""
+
+#: src/gui/guiVolumeChange.cpp
+msgid "Exit"
+msgstr ""
+
+#: src/gui/guiVolumeChange.cpp
+msgid "Muted"
+msgstr ""
+
+#: src/gui/guiVolumeChange.cpp
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr ""
+
+#. ~ Imperative, as in "Enter/type in text".
+#. Don't forget the space.
+#: src/gui/modalMenu.cpp
+msgid "Enter "
+msgstr ""
+
+#. ~ DO NOT TRANSLATE THIS LITERALLY!
+#. This is a special string which needs to contain the translation's
+#. language code (e.g. "de" for German).
+#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp
+msgid "LANG_CODE"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(Android) Fixes the position of virtual joystick.\n"
+"If disabled, virtual joystick will center to first-touch's position."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
+"If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
+"circle."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n"
+"Can be used to move a desired point to (0, 0) to create a\n"
+"suitable spawn point, or to allow 'zooming in' on a desired\n"
+"point by increasing 'scale'.\n"
+"The default is tuned for a suitable spawn point for Mandelbrot\n"
+"sets with default parameters, it may need altering in other\n"
+"situations.\n"
+"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(X,Y,Z) scale of fractal in nodes.\n"
+"Actual fractal size will be 2 to 3 times larger.\n"
+"These numbers can be made very large, the fractal does\n"
+"not have to fit inside the world.\n"
+"Increase these to 'zoom' into the detail of the fractal.\n"
+"Default is for a vertically-squashed shape suitable for\n"
+"an island, set all 3 numbers equal for the raw shape."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the shape/size of ridged mountains."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the shape/size of rolling hills."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the shape/size of step mountains."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the size/occurrence of ridged mountain ranges."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the size/occurrence of rolling hills."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the size/occurrence of step mountain ranges."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that locates the river valleys and channels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D clouds"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D mode parallax strength"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise defining giant caverns."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"3D noise defining mountain structure and height.\n"
+"Also defines structure of floatland mountain terrain."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"3D noise defining structure of floatlands.\n"
+"If altered from the default, the noise 'scale' (0.7 by default) may need\n"
+"to be adjusted, as floatland tapering functions best when this noise has\n"
+"a value range of approximately -2.0 to 2.0."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise defining structure of river canyon walls."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise defining terrain."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise that determines number of dungeons per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"3D support.\n"
+"Currently supported:\n"
+"-    none: no 3d output.\n"
+"-    anaglyph: cyan/magenta color 3d.\n"
+"-    interlaced: odd/even line based polarisation screen support.\n"
+"-    topbottom: split screen top/bottom.\n"
+"-    sidebyside: split screen side by side.\n"
+"-    crossview: Cross-eyed 3d\n"
+"-    pageflip: quadbuffer based 3d.\n"
+"Note that the interlaced mode requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"A chosen map seed for a new map, leave empty for random.\n"
+"Will be overridden when creating a new world in the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "A message to be displayed to all clients when the server crashes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "A message to be displayed to all clients when the server shuts down."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ABM interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ABM time budget"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Absolute limit of queued blocks to emerge"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Acceleration in air"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Acceleration of gravity, in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active Block Modifiers"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active block management interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active block range"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active object send range"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Address to connect to.\n"
+"Leave this blank to start a local server.\n"
+"Note that the address field in the main menu overrides this setting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Adds particles when digging a node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k "
+"screens."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, c-format
+msgid ""
+"Adjusts the density of the floatland layer.\n"
+"Increase value to increase density. Can be positive or negative.\n"
+"Value = 0.0: 50% of volume is floatland.\n"
+"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n"
+"to be sure) creates a solid floatland layer."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Advanced"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Alters the light curve by applying 'gamma correction' to it.\n"
+"Higher values make middle and lower light levels brighter.\n"
+"Value '1.0' leaves the light curve unaltered.\n"
+"This only has significant effect on daylight and artificial\n"
+"light, it has very little effect on natural night light."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Always fly and fast"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ambient occlusion gamma"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Amount of messages a player may send per 10 seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Amplifies the valleys."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Anisotropic filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Announce server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Announce to this serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Append item name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Append item name to tooltip."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Apple trees noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Arm inertia"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Arm inertia, gives a more realistic movement of\n"
+"the arm when the camera moves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ask to reconnect after crash"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"At this distance the server will aggressively optimize which blocks are sent "
+"to\n"
+"clients.\n"
+"Small values potentially improve performance a lot, at the expense of "
+"visible\n"
+"rendering glitches (some blocks will not be rendered under water and in "
+"caves,\n"
+"as well as sometimes on land).\n"
+"Setting this to a value greater than max_block_send_distance disables this\n"
+"optimization.\n"
+"Stated in mapblocks (16 nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Automatic forward key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Automatically jump up single-node obstacles."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Automatically report to the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Autosave screen size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Autoscaling mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Aux1 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Aux1 key for climbing/descending"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Backward key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Base ground level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Base terrain height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Basic"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Basic privileges"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Beach noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Beach noise threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bilinear filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bind address"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Biome API temperature and humidity noise parameters"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Biome noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Block send optimize distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold and italic font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold and italic monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Build inside player"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Builtin"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n"
+"Only works on GLES platforms. Most users will not need to change this.\n"
+"Increasing can reduce artifacting on weaker GPUs.\n"
+"0.1 = Default, 0.25 = Good value for weaker tablets."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Camera smoothing"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Camera smoothing in cinematic mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Camera update toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave noise #1"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave noise #2"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave1 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave2 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern taper"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern upper limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Center of light curve boost range.\n"
+"Where 0.0 is minimum light level, 1.0 is maximum light level."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat command time message threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat font size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat log level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message count limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message format"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message kick threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message max length"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat weblinks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chunk size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cinematic mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cinematic mode key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clean transparent textures"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client and Server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client modding"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client side modding restrictions"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client side node lookup range restriction"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Climbing speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cloud radius"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clouds"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clouds are a client side effect."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clouds in menu"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Colored fog"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Colored shadows"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Comma-separated list of flags to hide in the content repository.\n"
+"\"nonfree\" can be used to hide packages which do not qualify as 'free "
+"software',\n"
+"as defined by the Free Software Foundation.\n"
+"You can also specify content ratings.\n"
+"These flags are independent from Minetest versions,\n"
+"so see a full list at https://content.minetest.net/help/content_flags/"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Comma-separated list of mods that are allowed to access HTTP APIs, which\n"
+"allow them to upload and download data to/from the internet."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Comma-separated list of trusted mods that are allowed to access insecure\n"
+"functions even when mod security is on (via request_insecure_environment())."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Command key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Connect glass"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Connect to external media server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Connects glass if supported by node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Console alpha"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Console color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Console height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ContentDB Flag Blacklist"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ContentDB Max Concurrent Downloads"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ContentDB URL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Continuous forward"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Continuous forward movement, toggled by autoforward key.\n"
+"Press the autoforward key again or the backwards movement to disable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Controls length of day/night cycle.\n"
+"Examples:\n"
+"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls sinking speed in liquid."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls steepness/depth of lake depressions."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls steepness/height of hills."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Controls width of tunnels, a smaller value creates wider tunnels.\n"
+"Value >= 10.0 completely disables generation of tunnels and avoids the\n"
+"intensive noise calculations."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Crash message"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Creative"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Crosshair alpha"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Crosshair alpha (opaqueness, between 0 and 255).\n"
+"This also applies to the object crosshair."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Crosshair color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Crosshair color (R,G,B).\n"
+"Also controls the object crosshair color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Damage"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Debug info toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Debug log file size threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Debug log level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dec. volume key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Decrease this to increase liquid resistance to movement."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dedicated server step"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default acceleration"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default game"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Default game when creating a new world.\n"
+"This will be overridden when creating a world from the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default password"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default privileges"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default report format"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default stack size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
+"but also uses more resources."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines areas where trees have apples."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines areas with sandy beaches."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines distribution of higher terrain and steepness of cliffs."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines distribution of higher terrain."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines full size of caverns, smaller values create larger caverns."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines large-scale river channel structure."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines location and terrain of optional hills and lakes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the base ground level."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the depth of the river channel."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the width of the river channel."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the width of the river valley."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines tree areas and tree density."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Delay between mesh updates on the client in ms. Increasing this will slow\n"
+"down the rate of mesh updates, thus reducing jitter on slower clients."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Delay in sending blocks after building"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Delay showing tooltips, stated in milliseconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Deprecated Lua API handling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Depth below which you'll find giant caverns."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Depth below which you'll find large caves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Description of server, to be displayed when players join and in the "
+"serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Desert noise threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Deserts occur when np_biome exceeds this value.\n"
+"When the 'snowbiomes' flag is enabled, this is ignored."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Desynchronize block animation"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dig key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Digging particles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Disable anticheat"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Disallow empty passwords"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Domain name of server, to be displayed in the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Double tap jump for fly"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Double-tapping the jump key toggles fly mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Drop item key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dump the mapgen debug information."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dungeon maximum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dungeon minimum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dungeon noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable IPv6 support (for both client and server).\n"
+"Required for IPv6 connections to work at all."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable Lua modding support on client.\n"
+"This support is experimental and API can change."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
+"On true translucent nodes cast colored shadows. This is expensive."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable console window"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable creative mode for all players"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable joysticks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable mod channels support."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable mod security"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable players getting damage and dying."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable random user input (only used for testing)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable register confirmation"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable register confirmation when connecting to server.\n"
+"If disabled, new account will be registered automatically."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable smooth lighting with simple ambient occlusion.\n"
+"Disable for speed or for different looks."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable to disallow old clients from connecting.\n"
+"Older clients are compatible in the sense that they will not crash when "
+"connecting\n"
+"to new servers, but they may not support all new features that you are "
+"expecting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable usage of remote media server (if provided by server).\n"
+"Remote servers offer a significantly faster way to download media (e.g. "
+"textures)\n"
+"when connecting to the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable vertex buffer objects.\n"
+"This should greatly improve graphics performance."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable view bobbing and amount of view bobbing.\n"
+"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable/disable running an IPv6 server.\n"
+"Ignored if bind_address is set.\n"
+"Needs enable_ipv6 to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables Hable's 'Uncharted 2' filmic tone mapping.\n"
+"Simulates the tone curve of photographic film and how this approximates the\n"
+"appearance of high dynamic range images. Mid-range contrast is slightly\n"
+"enhanced, highlights and shadows are gradually compressed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enables animation of inventory items."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enables caching of facedir rotated meshes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enables minimap."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables the sound system.\n"
+"If disabled, this completely disables all sounds everywhere and the in-game\n"
+"sound controls will be non-functional.\n"
+"Changing this setting requires a restart."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Engine profiling data print interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Entity methods"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Exponent of the floatland tapering. Alters the tapering behaviour.\n"
+"Value = 1.0 creates a uniform, linear tapering.\n"
+"Values > 1.0 create a smooth tapering suitable for the default separated\n"
+"floatlands.\n"
+"Values < 1.0 (for example 0.25) create a more defined surface level with\n"
+"flatter lowlands, suitable for a solid floatland layer."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "FPS when unfocused or paused"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "FSAA"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Factor noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fall bobbing factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fallback font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast mode acceleration"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast mode speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast movement"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Fast movement (via the \"Aux1\" key).\n"
+"This requires the \"fast\" privilege on the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Field of view"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Field of view in degrees."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"File in client/serverlist/ that contains your favorite servers displayed in "
+"the\n"
+"Multiplayer Tab."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filler depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filler depth noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filmic tone mapping"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Filtered textures can blend RGB values with fully-transparent neighbors,\n"
+"which PNG optimizers usually discard, often resulting in dark or\n"
+"light edges to transparent textures. Apply a filter to clean that up\n"
+"at texture load time. This is automatically enabled if mipmapping is enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "First of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "First of two 3D noises that together define tunnels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fixed map seed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fixed virtual joystick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland density"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland maximum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland minimum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland taper exponent"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland tapering distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland water level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fly key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Flying"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fog"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fog start"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fog toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font bold by default"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font italic by default"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font shadow"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font shadow alpha"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Font size of the recent chat text and chat prompt in point (pt).\n"
+"Value 0 will use the default font size."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Format of player chat messages. The following strings are valid "
+"placeholders:\n"
+"@name, @message, @timestamp (optional)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Format of screenshots."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Default Background Color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Default Background Opacity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Full-Screen Background Color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Full-Screen Background Opacity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec default background color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec default background opacity (between 0 and 255)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec full-screen background color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec full-screen background opacity (between 0 and 255)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Forward key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fourth of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fractal type"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fraction of the visible distance at which fog starts to be rendered"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"From how far blocks are generated for clients, stated in mapblocks (16 "
+"nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"From how far blocks are sent to clients, stated in mapblocks (16 nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"From how far clients know about objects, stated in mapblocks (16 nodes).\n"
+"\n"
+"Setting this larger than active_block_range will also cause the server\n"
+"to maintain active objects up to this distance in the direction the\n"
+"player is looking. (This can avoid mobs suddenly disappearing from view)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Full screen"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fullscreen mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "GUI scaling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "GUI scaling filter"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "GUI scaling filter txr2img"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Global callbacks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Global map generation attributes.\n"
+"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
+"and jungle grass, in all other mapgens this flag controls all decorations."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Gradient of light curve at maximum light level.\n"
+"Controls the contrast of the highest light levels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Gradient of light curve at minimum light level.\n"
+"Controls the contrast of the lowest light levels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Graphics"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Gravity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ground level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ground noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "HTTP mods"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "HUD scale factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "HUD toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Handling for deprecated Lua API calls:\n"
+"-    none: Do not log deprecated calls\n"
+"-    log: mimic and log backtrace of deprecated call (default).\n"
+"-    error: abort on usage of deprecated call (suggested for mod developers)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Have the profiler instrument itself:\n"
+"* Instrument an empty function.\n"
+"This estimates the overhead, that instrumentation is adding (+1 function "
+"call).\n"
+"* Instrument the sampler being used to update the statistics."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Heat blend noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Heat noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Height component of the initial window size. Ignored in fullscreen mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Height noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Height select noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hill steepness"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hill threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness1 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness2 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness3 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness4 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Homepage of server, to be displayed in the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Horizontal acceleration in air when jumping or falling,\n"
+"in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Horizontal and vertical acceleration in fast mode,\n"
+"in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Horizontal and vertical acceleration on ground or when climbing,\n"
+"in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar next key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar previous key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 1 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 10 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 11 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 12 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 13 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 14 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 15 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 16 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 17 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 18 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 19 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 2 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 20 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 21 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 22 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 23 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 24 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 25 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 26 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 27 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 28 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 29 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 3 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 30 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 31 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 32 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 4 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 5 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 6 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 7 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 8 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 9 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "How deep to make rivers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"How fast liquid waves will move. Higher = faster.\n"
+"If negative, liquid waves will move backwards.\n"
+"Requires waving liquids to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"How much the server will wait before unloading unused mapblocks.\n"
+"Higher value is smoother, but will use more RAM."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "How wide to make rivers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Humidity blend noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Humidity noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Humidity variation for biomes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "IPv6"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "IPv6 server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If FPS would go higher than this, limit it by sleeping\n"
+"to not waste CPU power for no benefit."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
+"enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled the server will perform map block occlusion culling based on\n"
+"on the eye position of the player. This can reduce the number of blocks\n"
+"sent to the client 50-80%. The client will not longer receive most "
+"invisible\n"
+"so that the utility of noclip mode is reduced."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled together with fly mode, player is able to fly through solid "
+"nodes.\n"
+"This requires the \"noclip\" privilege on the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
+"and\n"
+"descending."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, actions are recorded for rollback.\n"
+"This option is only read when server starts."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "If enabled, disable cheat prevention in multiplayer."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, invalid world data won't cause the server to shut down.\n"
+"Only enable this if you know what you are doing."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, makes move directions relative to the player's pitch when flying "
+"or swimming."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "If enabled, new players cannot join with an empty password."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, you can place blocks at the position (feet + eye level) where "
+"you stand.\n"
+"This is helpful when working with nodeboxes in small areas."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If the CSM restriction for node range is enabled, get_node calls are "
+"limited\n"
+"to this distance from the player to the node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If the execution of a chat command takes longer than this specified time in\n"
+"seconds, add the time information to the chat command message"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If the file size of debug.txt exceeds the number of megabytes specified in\n"
+"this setting when it is opened, the file is moved to debug.txt.1,\n"
+"deleting an older debug.txt.1 if it exists.\n"
+"debug.txt is only moved if this setting is positive."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "If this is set, players will always (re)spawn at the given position."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ignore world errors"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-Game"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-game chat console background alpha (opaqueness, between 0 and 255)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-game chat console background color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Inc. volume key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Initial vertical speed when jumping, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument builtin.\n"
+"This is usually only needed by core/builtin contributors"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Instrument chat commands on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument global callback functions on registration.\n"
+"(anything you pass to a minetest.register_*() function)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument the action function of Active Block Modifiers on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument the action function of Loading Block Modifiers on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Instrument the methods of entities on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Instrumentation"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Interval of saving important changes in the world, stated in seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Interval of sending time of day to clients."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Inventory items animations"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Inventory key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Invert mouse"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Invert vertical mouse movement."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Italic font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Italic monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Item entity TTL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Iterations"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Iterations of the recursive function.\n"
+"Increasing this increases the amount of fine detail, but also\n"
+"increases processing load.\n"
+"At iterations = 20 this mapgen has a similar load to mapgen V7."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick ID"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick button repetition interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick dead zone"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick frustum sensitivity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick type"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"W component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Has no effect on 3D fractals.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"X component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"Y component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"Z component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia w"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia x"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia z"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Jump key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Jumping speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for decreasing the viewing range.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for decreasing the volume.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for digging.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for dropping the currently selected item.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for increasing the viewing range.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for increasing the volume.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for jumping.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving fast in fast mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player backward.\n"
+"Will also disable autoforward, when active.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player forward.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player left.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player right.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for muting the game.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the chat window to type commands.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the chat window to type local commands.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the chat window.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the inventory.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for placing.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 11th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 12th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 13th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 14th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 15th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 16th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 17th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 18th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 19th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 20th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 21st hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 22nd hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 23rd hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 24th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 25th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 26th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 27th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 28th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 29th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 30th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 31st hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 32nd hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the eighth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the fifth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the first hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the fourth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the next item in the hotbar.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the ninth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the previous item in the hotbar.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the second hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the seventh hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the sixth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the tenth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the third hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for sneaking.\n"
+"Also used for climbing down and descending in water if aux1_descends is "
+"disabled.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for switching between first- and third-person camera.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for taking screenshots.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling autoforward.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling cinematic mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling display of minimap.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling fast mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling flying.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling noclip mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling pitch move mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the camera update. Only used for development\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of chat.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of debug info.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of fog.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of the HUD.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of the large chat console.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of the profiler. Used for development.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling unlimited view range.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key to use view zoom when possible.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Kick players who sent more than X messages per 10 seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lake steepness"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lake threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Language"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave maximum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave minimum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave proportion flooded"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large chat console key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Leaves style"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Leaves style:\n"
+"-   Fancy:  all faces visible\n"
+"-   Simple: only outer faces, if defined special_tiles are used\n"
+"-   Opaque: disable transparency"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Left key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Length of a server tick and the interval at which objects are generally "
+"updated over\n"
+"network."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Length of liquid waves.\n"
+"Requires waving liquids to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Length of time between Active Block Modifier (ABM) execution cycles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Length of time between NodeTimer execution cycles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Length of time between active block management cycles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Level of logging to be written to debug.txt:\n"
+"-    <nothing> (no logging)\n"
+"-    none (messages with no level)\n"
+"-    error\n"
+"-    warning\n"
+"-    action\n"
+"-    info\n"
+"-    verbose"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve boost"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve boost center"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve boost spread"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve gamma"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve high gradient"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve low gradient"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n"
+"Only mapchunks completely within the mapgen limit are generated.\n"
+"Value is stored per-world."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Limits number of parallel HTTP requests. Affects:\n"
+"-    Media fetch if server uses remote_media setting.\n"
+"-    Serverlist download and server announcement.\n"
+"-    Downloads performed by main menu (e.g. mod manager).\n"
+"Only has an effect if compiled with cURL."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid fluidity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid fluidity smoothing"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid loop max"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid queue purge time"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid sinking"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid update interval in seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid update tick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Load the game profiler"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Load the game profiler to collect game profiling data.\n"
+"Provides a /profiler command to access the compiled profile.\n"
+"Useful for mod developers and server operators."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Loading Block Modifiers"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lower Y limit of dungeons."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lower Y limit of floatlands."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Main menu script"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Make fog and sky colors depend on daytime (dawn/sunset) and view direction."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Makes all liquids opaque"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map Compression Level for Disk Storage"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map Compression Level for Network Transfer"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map directory"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map generation attributes specific to Mapgen Carpathian."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen Flat.\n"
+"Occasional lakes and hills can be added to the flat world."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen Fractal.\n"
+"'terrain' enables the generation of non-fractal terrain:\n"
+"ocean, islands and underground."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen Valleys.\n"
+"'altitude_chill': Reduces heat with altitude.\n"
+"'humid_rivers': Increases humidity around rivers.\n"
+"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n"
+"to become shallower and occasionally dry.\n"
+"'altitude_dry': Reduces humidity with altitude."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map generation attributes specific to Mapgen v5."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen v6.\n"
+"The 'snowbiomes' flag enables the new 5 biome system.\n"
+"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n"
+"the 'jungles' flag is ignored."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen v7.\n"
+"'ridges': Rivers.\n"
+"'floatlands': Floating land masses in the atmosphere.\n"
+"'caverns': Giant caves deep underground."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map generation limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map save interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map shadows update frames"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock mesh generation delay"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock mesh generator's MapBlock cache size in MB"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock unload timeout"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Carpathian"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Carpathian specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Flat"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Flat specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Fractal"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Fractal specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V5"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V5 specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V6"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V6 specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V7"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V7 specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Valleys"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Valleys specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen debug"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max block generate distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max block send distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max liquids processed per step."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max. clearobjects extra blocks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max. packets per iteration"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum FPS"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum FPS when the window is not focused, or when the game is paused."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum distance to render shadows."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum forceloaded blocks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum hotbar width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum limit of random number of large caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum limit of random number of small caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum liquid resistance. Controls deceleration when entering liquid at\n"
+"high speed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of blocks that are simultaneously sent per client.\n"
+"The maximum total count is calculated dynamically:\n"
+"max_total = ceil((#clients + max_users) * per_client / 4)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of blocks that can be queued for loading."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of blocks to be queued that are to be generated.\n"
+"This limit is enforced per player."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of blocks to be queued that are to be loaded from file.\n"
+"This limit is enforced per player."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of concurrent downloads. Downloads exceeding this limit will "
+"be queued.\n"
+"This should be lower than curl_parallel_limit."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of forceloaded mapblocks."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of mapblocks for client to be kept in memory.\n"
+"Set to -1 for unlimited amount."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of packets sent per send step, if you have a slow connection\n"
+"try reducing it, but don't reduce it to a number below double of targeted\n"
+"client number."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of players that can be connected simultaneously."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of recent chat messages to show"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of statically stored objects in a block."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum objects per block"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum proportion of current window to be used for hotbar.\n"
+"Useful if there's something to be displayed right or left of hotbar."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum simultaneous block sends per client"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum size of the out chat queue"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum size of the out chat queue.\n"
+"0 to disable queueing and -1 to make the queue size unlimited."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum time a file download (e.g. a mod download) may take, stated in "
+"milliseconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum time an interactive request (e.g. server list fetch) may take, "
+"stated in milliseconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum users"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Menus"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mesh cache"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Message of the day"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Message of the day displayed to players connecting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Method used to highlight selected object."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimal level of logging to be written to chat."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimap"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimap key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimap scan height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimum limit of random number of large caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimum limit of random number of small caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimum texture size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mipmapping"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mod channels"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Modifies the size of the HUD elements."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain height noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain variation noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain zero level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mouse sensitivity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mouse sensitivity multiplier."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mud noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Multiplier for fall bobbing.\n"
+"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mute key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mute sound"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Name of map generator to be used when creating a new world.\n"
+"Creating a world in the main menu will override this.\n"
+"Current mapgens in a highly unstable state:\n"
+"-    The optional floatlands of v7 (disabled by default)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Name of the player.\n"
+"When running a server, clients connecting with this name are admins.\n"
+"When starting from the main menu, this is overridden."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Name of the server, to be displayed when players join and in the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Near plane"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Network"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Network port to listen (UDP).\n"
+"This value will be overridden when starting from the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "New users need to input this password."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Noclip"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Noclip key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Node highlighting"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "NodeTimer interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Noises"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Number of emerge threads"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Number of emerge threads to use.\n"
+"Value 0:\n"
+"-    Automatic selection. The number of emerge threads will be\n"
+"-    'number of processors - 2', with a lower limit of 1.\n"
+"Any other value:\n"
+"-    Specifies the number of emerge threads, with a lower limit of 1.\n"
+"WARNING: Increasing the number of emerge threads increases engine mapgen\n"
+"speed, but this may harm game performance by interfering with other\n"
+"processes, especially in singleplayer and/or when running Lua code in\n"
+"'on_generated'. For many users the optimum setting may be '1'."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Number of extra blocks that can be loaded by /clearobjects at once.\n"
+"This is a trade-off between SQLite transaction overhead and\n"
+"memory consumption (4096=100MB, as a rule of thumb)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Online Content Repository"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Opaque liquids"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Open the pause menu when the window's focus is lost. Does not pause if a "
+"formspec is\n"
+"open."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path of the fallback font. Must be a TrueType font.\n"
+"This font will be used for certain languages or if the default font is "
+"unavailable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to save screenshots at. Can be an absolute or relative path.\n"
+"The folder will be created if it doesn't already exist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to shader directory. If no path is defined, default location will be "
+"used."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Path to texture directory. All textures are first searched from here."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to the default font. Must be a TrueType font.\n"
+"The fallback font will be used if the font cannot be loaded."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to the monospace font. Must be a TrueType font.\n"
+"This font is used for e.g. the console and profiler screen."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Pause on lost window focus"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Per-player limit of queued blocks load from disk"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Per-player limit of queued blocks to generate"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Physics"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Pitch move key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Pitch move mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Place key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Place repetition interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Player is able to fly without being affected by gravity.\n"
+"This requires the \"fly\" privilege on the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Player name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Player transfer distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Player versus player"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Poisson filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Port to connect to (UDP).\n"
+"Note that the port field in the main menu overrides this setting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Prevent digging and placing from repeating when holding the mouse buttons.\n"
+"Enable this when you dig or place too often by accident."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Prevent mods from doing insecure things like running shell commands."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Print the engine's profiling data in regular intervals (in seconds).\n"
+"0 = disable. Useful for developers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Privileges that players with basic_privs can grant"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Profiler"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Profiler toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Profiling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Prometheus listener address"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Prometheus listener address.\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"enable metrics listener for Prometheus on that address.\n"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Proportion of large caves that contain liquid."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Radius of cloud area stated in number of 64 node cloud squares.\n"
+"Values larger than 26 will start to produce sharp cutoffs at cloud area "
+"corners."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Raises terrain to make valleys around the rivers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Random input"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Range select key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Recent Chat Messages"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Regular font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Remote media"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Remote port"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Remove color codes from incoming chat messages\n"
+"Use this to stop players from being able to use color in their messages"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Replaces the default main menu with a custom one."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Report path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Restricts the access of certain client-side functions on servers.\n"
+"Combine the byteflags below to restrict client-side features, or set to 0\n"
+"for no restrictions:\n"
+"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n"
+"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n"
+"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n"
+"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n"
+"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n"
+"csm_restriction_noderange)\n"
+"READ_PLAYERINFO: 32 (disable get_player_names call client-side)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridge mountain spread noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridge noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridge underwater noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridged mountain size noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Right key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River channel depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River channel width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River valley width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Rollback recording"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Rolling hill size noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Rolling hills spread noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Round minimap"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Safe digging and placing"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sandy beaches occur when np_beach exceeds this value."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Save the map received by the client on disk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Save window size automatically when modified."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Saving map received from server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Scale GUI by a user specified value.\n"
+"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n"
+"This will smooth over some of the rough edges, and blend\n"
+"pixels when scaling down, at the cost of blurring some\n"
+"edge pixels when images are scaled by non-integer sizes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screen height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screen width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screenshot folder"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screenshot format"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screenshot quality"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Screenshot quality. Only used for JPEG format.\n"
+"1 means worst quality; 100 means best quality.\n"
+"Use 0 for default quality."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Seabed noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Second of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Second of two 3D noises that together define tunnels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Security"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Selection box border color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Selection box color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Selection box width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Selects one of 18 fractal types.\n"
+"1 = 4D \"Roundy\" Mandelbrot set.\n"
+"2 = 4D \"Roundy\" Julia set.\n"
+"3 = 4D \"Squarry\" Mandelbrot set.\n"
+"4 = 4D \"Squarry\" Julia set.\n"
+"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n"
+"6 = 4D \"Mandy Cousin\" Julia set.\n"
+"7 = 4D \"Variation\" Mandelbrot set.\n"
+"8 = 4D \"Variation\" Julia set.\n"
+"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n"
+"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n"
+"11 = 3D \"Christmas Tree\" Mandelbrot set.\n"
+"12 = 3D \"Christmas Tree\" Julia set.\n"
+"13 = 3D \"Mandelbulb\" Mandelbrot set.\n"
+"14 = 3D \"Mandelbulb\" Julia set.\n"
+"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n"
+"16 = 3D \"Cosine Mandelbulb\" Julia set.\n"
+"17 = 4D \"Mandelbulb\" Mandelbrot set.\n"
+"18 = 4D \"Mandelbulb\" Julia set."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server / Singleplayer"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server URL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server address"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server description"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server port"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server side occlusion culling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Serverlist URL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Serverlist file"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the language. Leave empty to use the system language.\n"
+"A restart is required after changing this."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Set the maximum character length of a chat message sent by clients."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the shadow strength.\n"
+"Lower value means lighter shadows, higher value means darker shadows."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the soft shadow radius size.\n"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the tilt of Sun/Moon orbit in degrees.\n"
+"Value of 0 means no tilt / vertical orbit.\n"
+"Minimum value: 0.0; maximum value: 60.0"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable Shadow Mapping.\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable waving leaves.\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable waving liquids (like water).\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable waving plants.\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Sets shadow texture quality to 32 bits.\n"
+"On false, 16 bits texture will be used.\n"
+"This can cause much more artifacts in the shadow."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shader path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Shaders allow advanced visual effects and may increase performance on some "
+"video\n"
+"cards.\n"
+"This only works with the OpenGL video backend."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow filter quality"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow map max distance in nodes to render shadows"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow map texture in 32 bits"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow map texture size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Shadow offset (in pixels) of the default font. If 0, then shadow will not be "
+"drawn."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow strength"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shape of the minimap. Enabled = round, disabled = square."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Show debug info"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Show entity selection boxes"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Show entity selection boxes\n"
+"A restart is required after changing this."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Show name tag backgrounds by default"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shutdown message"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n"
+"WARNING!: There is no benefit, and there are several dangers, in\n"
+"increasing this value above 5.\n"
+"Reducing this value increases cave and dungeon density.\n"
+"Altering this value is for special usage, leaving it unchanged is\n"
+"recommended."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Size of the MapBlock cache of the mesh generator. Increasing this will\n"
+"increase the cache hit %, reducing the data being copied from the main\n"
+"thread, thus reducing jitter."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sky Body Orbit Tilt"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Slice w"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Slope and fill work together to modify the heights."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small cave maximum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small cave minimum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small-scale humidity variation for blending biomes on borders."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small-scale temperature variation for blending biomes on borders."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Smooth lighting"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Smooths camera when looking around. Also called look or mouse smoothing.\n"
+"Useful for recording videos."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Smooths rotation of camera in cinematic mode. 0 to disable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Smooths rotation of camera. 0 to disable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sneak key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sneaking speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sneaking speed, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Soft shadow radius"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sound"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Specifies URL from which client fetches media instead of using UDP.\n"
+"$filename should be accessible from $remote_media$filename via cURL\n"
+"(obviously, remote_media should end with a slash).\n"
+"Files that are not present will be fetched the usual way."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Specifies the default stack size of nodes, items and tools.\n"
+"Note that mods or games may explicitly set a stack for certain (or all) "
+"items."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread of light curve boost range.\n"
+"Controls the width of the range to be boosted.\n"
+"Standard deviation of the light curve boost Gaussian."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Static spawnpoint"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Steepness noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Step mountain size noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Step mountain spread noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Strength of 3D mode parallax."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Strength of light curve boost.\n"
+"The 3 'boost' parameters define a range of the light\n"
+"curve that is boosted in brightness."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Strict protocol checking"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Strip color codes"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Surface level of optional water placed on a solid floatland layer.\n"
+"Water is disabled by default and will only be placed if this value is set\n"
+"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n"
+"upper tapering).\n"
+"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n"
+"When enabling water placement the floatlands must be configured and tested\n"
+"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n"
+"required value depending on 'mgv7_np_floatland'), to avoid\n"
+"server-intensive extreme water flow and to avoid vast flooding of the\n"
+"world surface below."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Synchronous SQLite"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Temperature variation for biomes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain alternative noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain base noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain higher noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Terrain noise threshold for hills.\n"
+"Controls proportion of world area covered by hills.\n"
+"Adjust towards 0.0 for a larger proportion."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Terrain noise threshold for lakes.\n"
+"Controls proportion of world area covered by lakes.\n"
+"Adjust towards 0.0 for a larger proportion."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain persistence noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Texture path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Texture size to render the shadow map on.\n"
+"This must be a power of two.\n"
+"Bigger numbers create better shadows but it is also more expensive."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Textures on a node may be aligned either to the node or to the world.\n"
+"The former mode suits better things like machines, furniture, etc., while\n"
+"the latter makes stairs and microblocks fit surroundings better.\n"
+"However, as this possibility is new, thus may not be used by older servers,\n"
+"this option allows enforcing it for certain node types. Note though that\n"
+"that is considered EXPERIMENTAL and may not work properly."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The URL for the content repository"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The dead zone of the joystick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The default format in which profiles are being saved,\n"
+"when calling `/profiler save [format]` without format."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The depth of dirt or other biome filler node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The file path relative to your worldpath in which profiles will be saved to."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The identifier of the joystick to use"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The length in pixels it takes for touch screen interaction to start."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The maximum height of the surface of waving liquids.\n"
+"4.0 = Wave height is two nodes.\n"
+"0.0 = Wave doesn't move at all.\n"
+"Default is 1.0 (1/2 node).\n"
+"Requires waving liquids to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The network interface that the server listens on."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The privileges that new users automatically get.\n"
+"See /privs in game for a full list on your server and mod configuration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The radius of the volume of blocks around every player that is subject to "
+"the\n"
+"active block stuff, stated in mapblocks (16 nodes).\n"
+"In active blocks objects are loaded and ABMs run.\n"
+"This is also the minimum range in which active objects (mobs) are "
+"maintained.\n"
+"This should be configured together with active_object_send_range_blocks."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The rendering back-end.\n"
+"A restart is required after changing this.\n"
+"Note: On Android, stick with OGLES1 if unsure! App may fail to start "
+"otherwise.\n"
+"On other platforms, OpenGL is recommended.\n"
+"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The sensitivity of the joystick axes for moving the\n"
+"in-game view frustum around."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The strength (darkness) of node ambient-occlusion shading.\n"
+"Lower is darker, Higher is lighter. The valid range of values for this\n"
+"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n"
+"set to the nearest valid value."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time (in seconds) that the liquids queue may grow beyond processing\n"
+"capacity until an attempt is made to decrease its size by dumping old queue\n"
+"items.  A value of 0 disables the functionality."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time budget allowed for ABMs to execute on each step\n"
+"(as a fraction of the ABM Interval)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time in seconds it takes between repeated events\n"
+"when holding down a joystick button combination."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time in seconds it takes between repeated node placements when holding\n"
+"the place button."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The type of joystick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n"
+"enabled. Also the vertical distance over which humidity drops by 10 if\n"
+"'altitude_dry' is enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Third of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Time in seconds for item entity (dropped items) to live.\n"
+"Setting it to -1 disables the feature."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Time of day when a new world is started, in millihours (0-23999)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Time send interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Time speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Timeout for client to remove unused map data from memory."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"To reduce lag, block transfers are slowed down when a player is building "
+"something.\n"
+"This determines how long they are slowed down after placing or removing a "
+"node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Toggle camera mode key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Tooltip delay"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Touch screen threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Trees noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Trilinear filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"True = 256\n"
+"False = 128\n"
+"Usable to make minimap smoother on slower machines."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Trusted mods"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "URL to the server list displayed in the Multiplayer Tab."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Undersampling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Undersampling is similar to using a lower screen resolution, but it applies\n"
+"to the game world only, keeping the GUI intact.\n"
+"It should give a significant performance boost at the cost of less detailed "
+"image.\n"
+"Higher values result in a less detailed image."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Unlimited player transfer distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Unload unused server data"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Upper Y limit of dungeons."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Upper Y limit of floatlands."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use 3D cloud look instead of flat."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use a cloud animation for the main menu background."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use anisotropic filtering when viewing at textures from an angle."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use bilinear filtering when scaling textures."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Use mipmapping to scale textures. May slightly increase performance,\n"
+"especially when using a high resolution texture pack.\n"
+"Gamma correct downscaling is not supported."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n"
+"This algorithm smooths out the 3D viewport while keeping the image sharp,\n"
+"but it doesn't affect the insides of textures\n"
+"(which is especially noticeable with transparent textures).\n"
+"Visible spaces appear between nodes when shaders are disabled.\n"
+"If set to 0, MSAA is disabled.\n"
+"A restart is required after changing this option."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use trilinear filtering when scaling textures."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "VBO"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "VSync"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley fill"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley profile"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley slope"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Variation of biome filler depth."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Variation of maximum mountain height (in nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Variation of number of caves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Variation of terrain vertical scale.\n"
+"When noise is < -0.55 terrain is near-flat."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Varies depth of biome surface nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Varies roughness of terrain.\n"
+"Defines the 'persistence' value for terrain_base and terrain_alt noises."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Varies steepness of cliffs."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Vertical climbing speed, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Vertical screen synchronization."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Video driver"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View bobbing factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View distance in nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View range decrease key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View range increase key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View zoom key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Viewing range"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Virtual joystick triggers Aux1 button"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Volume"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Volume of all sounds.\n"
+"Requires the sound system to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"W coordinate of the generated 3D slice of a 4D fractal.\n"
+"Determines which 3D slice of the 4D shape is generated.\n"
+"Alters the shape of the fractal.\n"
+"Has no effect on 3D fractals.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Walking and flying speed, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Walking speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Walking, flying and climbing speed in fast mode, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Water level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Water surface level of the world."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving Nodes"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving leaves"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids wave height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids wave speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids wavelength"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving plants"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"When gui_scaling_filter is true, all GUI images need to be\n"
+"filtered in software, but some images are generated directly\n"
+"to hardware (e.g. render-to-texture for nodes in inventory)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"When gui_scaling_filter_txr2img is true, copy those images\n"
+"from hardware to software for scaling.  When false, fall back\n"
+"to the old scaling method, for video drivers that don't\n"
+"properly support downloading textures back from hardware."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
+"can be blurred, so automatically upscale them with nearest-neighbor\n"
+"interpolation to preserve crisp pixels. This sets the minimum texture size\n"
+"for the upscaled textures; higher values look sharper, but require more\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
+"bilinear/trilinear/anisotropic filtering is enabled.\n"
+"This is also used as the base node texture size for world-aligned\n"
+"texture autoscaling."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether name tag backgrounds should be shown by default.\n"
+"Mods may still set a background."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Whether node texture animations should be desynchronized per mapblock."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether players are shown to clients without any range limit.\n"
+"Deprecated, use the setting player_transfer_distance instead."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Whether to allow players to damage and kill each other."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether to ask clients to reconnect after a (Lua) crash.\n"
+"Set this to true if your server is set up to restart automatically."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Whether to fog out the end of the visible area."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether to mute sounds. You can unmute sounds at any time, unless the\n"
+"sound system is disabled (enable_sound=false).\n"
+"In-game, you can toggle the mute state with the mute key or by using the\n"
+"pause menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether to show the client debug info (has the same effect as hitting F5)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Width component of the initial window size. Ignored in fullscreen mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Width of the selection box lines around nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Windows systems only: Start Minetest with the command line window in the "
+"background.\n"
+"Contains the same information as the file debug.txt (default name)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"World directory (everything in the world is stored here).\n"
+"Not needed if starting from the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "World start time"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"World-aligned textures may be scaled to span several nodes. However,\n"
+"the server may not send the scale you want, especially if you use\n"
+"a specially-designed texture pack; with this option, the client tries\n"
+"to determine the scale automatically basing on the texture size.\n"
+"See also texture_min_size.\n"
+"Warning: This option is EXPERIMENTAL!"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "World-aligned textures mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y of flat ground."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Y of mountain density gradient zero level. Used to shift mountains "
+"vertically."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y of upper limit of large caves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-distance over which caverns expand to full size."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Y-distance over which floatlands taper from full density to nothing.\n"
+"Tapering starts at this distance from the Y limit.\n"
+"For a solid floatland layer, this controls the height of hills/mountains.\n"
+"Must be less than or equal to half the distance between the Y limits."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of average terrain surface."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of cavern upper limit."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of higher terrain that creates cliffs."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of lower terrain and seabed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of seabed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "cURL file download timeout"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "cURL interactive timeout"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "cURL parallel limit"
+msgstr ""
index 53b706f5f8f322336067b9d93c0b17c0cd8f4575..0cddb4abfae4296749b13ee271096d3ca6668cee 100644 (file)
@@ -8,13 +8,13 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 #: builtin/client/chatcommands.lua
@@ -53,10 +53,6 @@ msgstr ""
 msgid "The out chat queue is now empty."
 msgstr ""
 
-#: builtin/client/death_formspec.lua
-msgid "You died."
-msgstr ""
-
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "You died"
 msgstr ""
@@ -94,6 +90,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "The server has requested a reconnect:"
 msgstr ""
@@ -243,6 +243,10 @@ msgstr ""
 msgid "Failed to download $1"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Already installed"
 msgstr ""
@@ -354,11 +358,11 @@ msgid "Very large caverns deep in the underground"
 msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
-msgid "Sea level rivers"
+msgid "Rivers"
 msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
-msgid "Rivers"
+msgid "Sea level rivers"
 msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
@@ -533,11 +537,11 @@ msgid "Create"
 msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
-msgid "A world named \"$1\" already exists"
+msgid "No game selected"
 msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
-msgid "No game selected"
+msgid "A world named \"$1\" already exists"
 msgstr ""
 
 #: builtin/mainmenu/dlg_delete_content.lua
@@ -617,7 +621,7 @@ msgid "Octaves"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -743,14 +747,6 @@ msgstr ""
 msgid "Unable to install a game as a $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "$1 mods"
 msgstr ""
@@ -846,27 +842,27 @@ msgid "Install games from ContentDB"
 msgstr ""
 
 #: builtin/mainmenu/tab_local.lua
-msgid "Select Mods"
+msgid "Creative Mode"
 msgstr ""
 
 #: builtin/mainmenu/tab_local.lua
-msgid "New"
+msgid "Enable Damage"
 msgstr ""
 
 #: builtin/mainmenu/tab_local.lua
-msgid "Select World:"
+msgid "Host Server"
 msgstr ""
 
 #: builtin/mainmenu/tab_local.lua
-msgid "Creative Mode"
+msgid "Select Mods"
 msgstr ""
 
 #: builtin/mainmenu/tab_local.lua
-msgid "Enable Damage"
+msgid "New"
 msgstr ""
 
 #: builtin/mainmenu/tab_local.lua
-msgid "Host Server"
+msgid "Select World:"
 msgstr ""
 
 #: builtin/mainmenu/tab_local.lua
@@ -1126,15 +1122,11 @@ msgstr ""
 msgid "Dynamic shadows"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua
 msgid "Settings"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1187,7 +1179,7 @@ msgid "Provided world path doesn't exist: "
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1202,10 +1194,19 @@ msgstr ""
 msgid "Creating server..."
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Singleplayer"
 msgstr ""
@@ -1218,10 +1219,29 @@ msgstr ""
 msgid "Resolving address..."
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Item definitions..."
 msgstr ""
@@ -1323,6 +1343,26 @@ msgstr ""
 msgid "Cinematic mode disabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward enabled"
 msgstr ""
@@ -1489,25 +1529,26 @@ msgstr ""
 msgid "Off"
 msgstr ""
 
+#. ~ PvP = Player versus Player
 #: src/client/game.cpp
-msgid "- Damage: "
+msgid "- PvP: "
 msgstr ""
 
 #: src/client/game.cpp
-msgid "- Creative Mode: "
+msgid "- Public: "
 msgstr ""
 
-#. ~ PvP = Player versus Player
 #: src/client/game.cpp
-msgid "- PvP: "
+msgid "- Server Name: "
 msgstr ""
 
 #: src/client/game.cpp
-msgid "- Public: "
+#, c-format
+msgid "The server is probably running a different version of %s."
 msgstr ""
 
 #: src/client/game.cpp
-msgid "- Server Name: "
+msgid "A serialization error occurred:"
 msgstr ""
 
 #: src/client/game.cpp
@@ -1818,6 +1859,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp
 #, c-format
 msgid ""
@@ -2005,7 +2054,8 @@ msgid "Change"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
@@ -2258,11 +2308,11 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2272,7 +2322,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3064,12 +3114,12 @@ msgid "Basic"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -3121,6 +3171,16 @@ msgid ""
 "Disable for speed or for different looks."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Clouds"
 msgstr ""
@@ -3163,7 +3223,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -3214,7 +3274,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -3378,7 +3438,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3398,8 +3458,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
 "filtering."
 msgstr ""
 
@@ -3409,8 +3469,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3420,20 +3480,20 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3443,8 +3503,8 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3453,9 +3513,9 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3803,7 +3863,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3837,7 +3897,7 @@ msgid "HUD scale factor"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4043,17 +4103,6 @@ msgstr ""
 msgid "Append item name to tooltip."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Font bold by default"
 msgstr ""
@@ -4086,7 +4135,22 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4095,9 +4159,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
@@ -4118,7 +4180,11 @@ msgid "Monospace font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4127,9 +4193,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -4151,9 +4215,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -4207,6 +4269,14 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
 msgstr ""
@@ -4256,6 +4326,24 @@ msgstr ""
 msgid "Client"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat weblinks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Network"
 msgstr ""
@@ -4288,9 +4376,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4540,11 +4628,10 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5002,7 +5089,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5038,11 +5125,10 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5285,11 +5371,11 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat commands"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5492,7 +5578,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6551,12 +6637,3 @@ msgid ""
 "be queued.\n"
 "This should be lower than curl_parallel_limit."
 msgstr ""
-
-#: src/gui/guiChatConsole.cpp
-msgid "Opening webpage"
-msgstr ""
-
-#: src/gui/guiChatConsole.cpp
-msgid "Failed to open webpage"
-msgstr ""
-
index 7c7f189cda070b3865241111d3dd7563222bee76..d1a4e213ebac1233cd6398915309be271ccb3a8b 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-06-10 14:35+0000\n"
 "Last-Translator: Avyukt More <moreavyukt1@outlook.com>\n"
 "Language-Team: Marathi <https://hosted.weblate.org/projects/minetest/"
@@ -64,11 +64,6 @@ msgstr "पुनर्जन्म"
 msgid "You died"
 msgstr "तू मेलास"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "तू मेलास"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -98,6 +93,10 @@ msgstr ""
 msgid "OK"
 msgstr "ठीक आहे"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "त्रुटी आढळली"
@@ -296,6 +295,10 @@ msgstr "डाउनलोड $1"
 msgid "Install missing dependencies"
 msgstr "गहाळ अवलंबित्व डाउनलोड करा"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -621,7 +624,7 @@ msgid "Offset"
 msgstr "ऑफसेट"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -731,14 +734,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1103,10 +1098,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1139,7 +1130,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1168,7 +1159,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1209,14 +1200,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1238,6 +1221,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "एक त्रुटी आली:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1246,6 +1239,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1254,6 +1263,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1266,6 +1279,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1274,6 +1291,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1297,6 +1318,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1489,6 +1515,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1823,6 +1864,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "$१ डाउनलोड करू नाही शकत"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2018,7 +2068,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2225,6 +2276,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2491,6 +2546,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2524,7 +2583,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2543,6 +2602,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2618,6 +2683,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2709,7 +2790,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2786,8 +2867,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2905,6 +2986,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2951,7 +3036,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2979,13 +3071,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3070,6 +3155,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3254,11 +3345,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3267,6 +3362,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3326,10 +3432,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3378,7 +3480,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3810,7 +3912,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3894,7 +3996,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4723,7 +4825,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5016,7 +5118,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5027,6 +5129,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5148,7 +5254,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5172,11 +5278,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5199,17 +5307,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5312,9 +5416,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5607,26 +5711,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5717,7 +5813,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5822,6 +5918,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5932,7 +6036,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5950,7 +6054,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6019,7 +6123,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6112,6 +6216,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6182,7 +6290,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6365,6 +6473,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6386,7 +6498,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6394,14 +6506,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6527,24 +6632,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6556,3 +6643,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr ""
+
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "तू मेलास"
index 5985a4220e52ee3b3965e4dd2a7021ef2d4d3928..e1d067e7961c6ce96042b0e979a0067c17228bf4 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Malay (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-06-01 16:17+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-30 18:51+0000\n"
 "Last-Translator: Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat "
 "Yasuyoshi <translation@mnh48.moe>\n"
 "Language-Team: Malay <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -13,94 +13,87 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Saiz maksimum baris gilir keluar sembang"
+msgstr "Padam baris gilir sembang keluar"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Perintah sembang"
+msgstr "Perintah kosong."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Keluar ke Menu"
+msgstr "Keluar ke menu utama"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Arahan tempatan"
+msgstr "Perintah tidak sah: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Perintah dikeluarkan: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Pemain Perseorangan"
+msgstr "Senaraikan pemain dalam talian"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Pemain Perseorangan"
+msgstr "Pemain dalam talian: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Baris gilir sembang keluar kini kosong."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Perintah ini dilumpuhkan oleh pelayan."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
-msgstr "Lahir semula"
+msgstr "Jelma semula"
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "You died"
 msgstr "Anda telah meninggal"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Anda telah meninggal"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Arahan tempatan"
+msgstr "Perintah tersedia:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Arahan tempatan"
+msgstr "Perintah tersedia: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Perintah tidak tersedia: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Dapatkan bantuan untuk perintah"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Gunakan '.help <perintah>' untuk dapatkan maklumat lanjut, atau '.help all' "
+"untuk senaraikan kesemuanya."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <perintah>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<tiada yang tersedia>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Berlakunya ralat dalam skrip Lua:"
@@ -303,6 +296,10 @@ msgstr "Pasang $1"
 msgid "Install missing dependencies"
 msgstr "Pasang kebergantungan yang hilang"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Pasang: Jenis fail tidak disokong atau arkib rosak"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -632,7 +629,7 @@ msgid "Offset"
 msgstr "Ofset"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Penerusan"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -742,14 +739,6 @@ msgstr "Pasang Mods: Gagal mencari nama mods sebenar untuk: $1"
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "Pasang Mods: tidak jumpa nama folder yang sesuai untuk pek mods $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Pasang: Jenis fail \"$1\" tidak disokong atau arkib rosak"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Pasang: fail: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Tidak jumpa mods atau pek mods yang sah"
@@ -786,16 +775,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Perihal"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Penyumbang Aktif"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Jarak penghantaran objek aktif"
+msgstr "Pengemas gabung aktif:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -903,7 +891,7 @@ msgstr "Tiada dunia dicipta atau dipilih!"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Password"
-msgstr "Kata Laluan"
+msgstr "Kata laluan"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
@@ -930,9 +918,8 @@ msgid "Start Game"
 msgstr "Mulakan Permainan"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Alamat: "
+msgstr "Alamat"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -948,22 +935,20 @@ msgstr "Mod Kreatif"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Boleh cedera"
+msgstr "Boleh cedera / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Padam Kegemaran"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "Kegemaran"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Pelayan Tidak Serasi"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -974,18 +959,16 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Umumkan Pelayan"
+msgstr "Pelayan Awam"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Segarkan semula"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Perihal pelayan"
+msgstr "Keterangan Pelayan"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1028,13 +1011,12 @@ msgid "Connected Glass"
 msgstr "Kaca Bersambungan"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Bayang fon"
+msgstr "Bayang dinamik"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Bayang dinamik: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1042,15 +1024,15 @@ msgstr "Daun Beragam"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Tinggi"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Rendah"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Sederhana"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1124,10 +1106,6 @@ msgstr "Pencahayaan Lembut"
 msgid "Texturing:"
 msgstr "Jalinan:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Untuk membolehkan pembayang, pemacu OpenGL mesti digunakan."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Pemetaan Tona"
@@ -1142,11 +1120,11 @@ msgstr "Penapisan Trilinear"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Ultra Tinggi"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Sangat Rendah"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1160,7 +1138,7 @@ msgstr "Cecair Bergelora"
 msgid "Waving Plants"
 msgstr "Tumbuhan Bergoyang"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Sambungan tamat tempoh."
 
@@ -1189,8 +1167,8 @@ msgid "Connection error (timed out?)"
 msgstr "Ralat dalam penyambungan (tamat tempoh?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Tidak jumpa atau tidak boleh muatkan permainan \""
+msgid "Could not find or load game"
+msgstr "Tidak jumpa atau tidak boleh muatkan permainan"
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1233,14 +1211,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Alamat: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Mod Kreatif: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Boleh cedera: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Mod: "
@@ -1262,6 +1232,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Nama Pelayan: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Telah berlakunya ralat penyirian:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Capaian dinafikan. Sebab: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Pergerakan automatik dilumpuhkan"
@@ -1270,6 +1249,22 @@ msgstr "Pergerakan automatik dilumpuhkan"
 msgid "Automatic forward enabled"
 msgstr "Pergerakan automatik dibolehkan"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Batas blok disembunyikan"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Batas blok ditunjukkan untuk semua blok"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Batas blok ditunjukkan untuk blok semasa"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Batas blok ditunjukkan untuk blok berhampiran"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kemas kini kamera dilumpuhkan"
@@ -1278,6 +1273,10 @@ msgstr "Kemas kini kamera dilumpuhkan"
 msgid "Camera update enabled"
 msgstr "Kemas kini kamera dibolehkan"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Tidak boleh tunjuk batas blok (perlukan keistimewaan 'basic_debug')"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Tukar Kata Laluan"
@@ -1290,6 +1289,10 @@ msgstr "Mod sinematik dilumpuhkan"
 msgid "Cinematic mode enabled"
 msgstr "Mod sinematik dibolehkan"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Klien dinyahsambung"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Skrip pihak klien dilumpuhkan"
@@ -1298,6 +1301,10 @@ msgstr "Skrip pihak klien dilumpuhkan"
 msgid "Connecting to server..."
 msgstr "Sedang menyambung kepada pelayan..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Sambungan gagal untuk sebab yang tidak diketahui"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Teruskan"
@@ -1335,6 +1342,11 @@ msgstr ""
 "- Roda tetikus: pilih item\n"
 "- %s: sembang\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Tidak mampu menyelesaikan alamat: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Sedang mencipta klien..."
@@ -1466,9 +1478,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Peta mini dilumpuhkan oleh permainan atau mods"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Pemain Perseorangan"
+msgstr "Pemain Ramai"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1542,6 +1553,21 @@ msgstr "Sistem bunyi tidak disokong di binaan ini"
 msgid "Sound unmuted"
 msgstr "Bunyi dinyahbisukan"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Kemungkinan pelayan menjalankan versi %s yang berlainan."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Tidak mampu sambung ke %s kerana IPv6 dilumpuhkan"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Tidak mampu dengar di %s kerana IPv6 dilumpuhkan"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1876,6 +1902,14 @@ msgstr "Peta mini dalam mod permukaan, Zum x%d"
 msgid "Minimap in texture mode"
 msgstr "Peta mini dalam mod tekstur"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Gagal buka laman sesawang"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Membuka laman sesawang"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Kata laluan tidak padan!"
@@ -1904,9 +1938,8 @@ msgid "Proceed"
 msgstr "Teruskan"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Istimewa\" = panjat turun"
+msgstr "\"Aux1\" = panjat turun"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1918,7 +1951,7 @@ msgstr "Lompat automatik"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1926,7 +1959,7 @@ msgstr "Ke Belakang"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Batas blok"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -1938,7 +1971,7 @@ msgstr "Sembang"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Command"
-msgstr "Arahan"
+msgstr "Perintah"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Console"
@@ -1987,12 +2020,12 @@ msgstr "Kekunci telah digunakan untuk fungsi lain"
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
 msgstr ""
-"Ikatan kekunci. (Jika menu ini berselerak, padam sesetengah benda dari fail "
+"Ikatan kekunci. (Jika menu ini berselerak, buang sesetengah benda dari fail "
 "minetest.conf)"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Local command"
-msgstr "Arahan tempatan"
+msgstr "Perintah tempatan"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Mute"
@@ -2079,8 +2112,9 @@ msgid "Muted"
 msgstr "Dibisukan"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Kekuatan Bunyi: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Kekuatan Bunyi: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2105,14 +2139,13 @@ msgstr ""
 "berdasarkan kedudukan sentuhan pertama."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Guna kayu bedik maya untuk picu butang \"aux\".\n"
-"Jika dibolehkan, kayu bedik maya juga akan menekan butang \"aux\" apabila "
+"(Android) Guna kayu bedik maya untuk picu butang \"Aux1\".\n"
+"Jika dibolehkan, kayu bedik maya juga akan menekan butang \"Aux1\" apabila "
 "berada di luar bulatan utama."
 
 #: src/settings_translation_file.cpp
@@ -2128,10 +2161,10 @@ msgid ""
 msgstr ""
 "(X,Y,Z) Ofset fraktal dari pusat dunia dalam unit 'skala'.\n"
 "Boleh guna untuk pindahkan titik yang diingini ke (0, 0)\n"
-"untuk cipta titik kelahiran yang sesuai, atau untuk\n"
+"untuk cipta titik jelma yang sesuai, atau untuk\n"
 "membolehkan 'zum masuk' pada titik yang diinginkan\n"
 "dengan menaikkan 'skala'.\n"
-"Nilai lalai disesuaikan untuk titik kelahiran sesuai untuk set Mandelbrot\n"
+"Nilai lalai disesuaikan untuk titik jelma sesuai untuk set Mandelbrot\n"
 "dengan parameter lalai, ia mungkin perlu diubah untuk situasi yang lain.\n"
 "Julat kasarnya -2 sehingga 2. Darabkan dengan 'skala' untuk ofset dalam nod."
 
@@ -2249,13 +2282,14 @@ msgid ""
 msgstr ""
 "Sokongan 3D.\n"
 "Yang disokong pada masa ini:\n"
-"-    tiada: tiada output 3D.\n"
-"-    anaglif: 3D warna biru/merah.\n"
-"-    selang-seli: garis genap/ganjil berdasarkan sokongan skrin polarisasi.\n"
-"-    atas-bawah: pisah skrin atas/bawah.\n"
-"-    kiri-kanan: pisah skrin kiri/kanan.\n"
-"-    silang lihat: 3D mata bersilang\n"
-"-    selak halaman: 3D berasaskan penimbal kuad.\n"
+"-    none (tiada): untuk tiada output 3D.\n"
+"-    anaglyph (anaglif): 3D warna biru/merah.\n"
+"-    interlaced (selang-seli): garis genap/ganjil berdasarkan sokongan skrin "
+"polarisasi.\n"
+"-    topbottom (atas-bawah): pisah skrin atas/bawah.\n"
+"-    sidebyside (kiri-kanan): pisah skrin kiri/kanan.\n"
+"-    crossview (silang lihat): 3D mata bersilang\n"
+"-    pageflip (selak halaman): 3D berasaskan penimbal kuad.\n"
 "Ambil perhatian bahawa mod selang-seli memerlukan pembayang."
 
 #: src/settings_translation_file.cpp
@@ -2332,6 +2366,12 @@ msgstr ""
 "Laraskan konfigurasi DPI ke skrin anda (bukan X11/Android sahaja) cth. untuk "
 "skrin 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Laraskan ketumpatan paparan yang dikesan, digunakan untuk menyesuaikan "
+"elemen UI."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2439,10 +2479,11 @@ msgstr ""
 "Pada jarak ini, pelayan akan mengoptimumkan secara agresif blok yang mana\n"
 "akan dihantar kepada klien.\n"
 "Nilai lebih kecil berkemungkinan boleh meningkatkan prestasi dengan banyak,\n"
-"dengan mengorbankan glic penterjemahan tampak (sesetengah blok tidak akan\n"
-"diterjemahkan di bawah air dan dalam gua, kekadang turut berlaku atas "
+"dengan mengorbankan glic kemas gabung tampak (sesetengah blok tidak akan\n"
+"dikemas gabung di bawah air dan dalam gua, kekadang turut berlaku atas "
 "daratan).\n"
-"Menetapkan nilai ini lebih bear daripada nilai max_block_send_distance akan\n"
+"Menetapkan nilai ini lebih besar daripada nilai max_block_send_distance "
+"akan\n"
 "melumpuhkan pengoptimuman ini.\n"
 "Nyatakan dalam unit blokpeta (16 nod)."
 
@@ -2467,14 +2508,12 @@ msgid "Autoscaling mode"
 msgstr "Mod skala automatik"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Kekunci lompat"
+msgstr "Kekunci Aux1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Kekunci untuk memanjat/menurun"
+msgstr "Kekunci Aux1 untuk memanjat/menurun"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2626,9 +2665,12 @@ msgstr ""
 "Di mana 0.0 ialah aras cahaya minimum, 1.0 ialah maksimum."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Nilai ambang tendang mesej sembang"
+msgstr "Nilai ambang mesej masa perintah sembang"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Perintah sembang"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2663,8 +2705,8 @@ msgid "Chat toggle key"
 msgstr "Kekunci togol sembang"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Perintah sembang"
+msgid "Chat weblinks"
+msgstr "Pautan sesawang sembang"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2682,6 +2724,14 @@ msgstr "Kekunci mod sinematik"
 msgid "Clean transparent textures"
 msgstr "Bersihkan tekstur lut sinar"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Pautan sesawang boleh klik (klik-tengah atau Ctrl+klik-kiri) dibolehkan "
+"dalam output konsol sembang."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klien"
@@ -2727,9 +2777,8 @@ msgid "Colored fog"
 msgstr "Kabut berwarna"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Kabut berwarna"
+msgstr "Bayang berwarna"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2756,7 +2805,7 @@ msgid ""
 "Comma-separated list of mods that are allowed to access HTTP APIs, which\n"
 "allow them to upload and download data to/from the internet."
 msgstr ""
-"Senarai mods yang dibenarkan mengakses API HTTP dipisahkan dengan koma,\n"
+"Senarai mods yang dibenarkan mencapai API HTTP dipisahkan dengan koma,\n"
 "ini membolehkan mereka memuat naik kepada atau muat turun daripada internet."
 
 #: src/settings_translation_file.cpp
@@ -2765,13 +2814,37 @@ msgid ""
 "functions even when mod security is on (via request_insecure_environment())."
 msgstr ""
 "Senarai dipisahkan dengan koma untuk mods boleh dipercayai yang dibenarkan "
-"mengakses\n"
-"fungsi tidak selamat walaupun ketika keselamatan mods diaktifkan (melalui "
+"mencapai fungsi\n"
+"tidak selamat walaupun ketika keselamatan mods diaktifkan (melalui "
 "request_insecure_environment())."
 
 #: src/settings_translation_file.cpp
 msgid "Command key"
-msgstr "Kekunci arahan"
+msgstr "Kekunci perintah"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Tahap pemampatan untuk digunakan apabila menyimpan blokpeta ke cakera.\n"
+"-1 - guna tahap pemampatan lalai\n"
+"0 - pemampatan paling sedikit, paling laju\n"
+"9 - pemampatan paling banyak, paling lambat"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Tahap pemampatan untuk digunakan apabila menghantar blokpeta kepada klien.\n"
+"-1 - guna tahap pemampatan lalai\n"
+"0 - pemampatan paling sedikit, paling laju\n"
+"9 - pemampatan paling banyak, paling lambat"
 
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
@@ -2874,10 +2947,10 @@ msgstr "Nilai alfa rerambut silang"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Nilai alfa rerambut silang (kelegapan, antara 0 dan 255).\n"
-"Juga mengawal warna rerambut silang objek"
+"Nilai ini juga memberi kesan kepada rerambut silang objek."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2958,10 +3031,13 @@ msgstr "Saiz tindanan lalai"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Mentakrifkan kualiti penapisan bayang.\n"
+"Tetapan ini menyelakukan kesan bayang lembut dengan menggunakan\n"
+"PCF atau cakera Poisson tetapi turut menggunakan lebih banyak sumber."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3088,6 +3164,10 @@ msgstr "Melumpuhkan antitipu"
 msgid "Disallow empty passwords"
 msgstr "Menolak kata laluan kosong"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Faktor Skala Ketumpatan Paparan"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Nama domain pelayan, untuk dipaparkan dalam senarai pelayan."
@@ -3139,9 +3219,22 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Membolehkan penapisan cakera Poisson.\n"
+"Jika dibenarkan, gunakan cakera Poisson untuk membuat \"bayang lembut\". "
+"Jika tidak, gunakan penapisan PCF."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Membolehkan bayang berwarna. \n"
+"Jika dibenarkan, nod lut cahaya mengeluarkan bayang berwarna. Fungsi ini "
+"sangat berat."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3167,13 +3260,6 @@ msgstr "Membolehkan keselamatan mods"
 msgid "Enable players getting damage and dying."
 msgstr "Membolehkan pemain menerima kecederaan dan mati."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Membolehkan input pengguna secara rawak (hanya untuk percubaan)."
@@ -3196,7 +3282,7 @@ msgid ""
 "Disable for speed or for different looks."
 msgstr ""
 "Membolehkan pencahayaan lembut dengan oklusi sekitar yang ringkas.\n"
-"Lumpuhkannya untuk kelajuan atau untuk kelihatan berbeza."
+"Lumpuhkannya untuk kelajuan atau untuk kelihatan berlainan."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3287,6 +3373,16 @@ msgstr ""
 "dan kawalan bunyi dalam permainan tidak akan berfungsi.\n"
 "Pengubahan tetapan ini memerlukan permulaan semula."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+"Membolehkan keseimbangan yang mengurangkan muatan CPU atau meningkatkan "
+"prestasi kemas gabung\n"
+"dengan mengorbankan glic visual yang kecil yang tidak memberi kesan kepada "
+"kebolehan bermain permainan."
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Selang masa cetak data pemprofilan enjin"
@@ -3348,13 +3444,12 @@ msgid "Fast movement"
 msgstr "Pergerakan pantas"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Bergerak pantas (dengan kekunci \"istimewa\").\n"
-"Ini memerlukan keistimewaan \"pergerakan pantas\" dalam pelayan tersebut."
+"Bergerak pantas (dengan kekunci \"Aux1\").\n"
+"Ini memerlukan keistimewaan \"pergerakan pantas\" di pelayan tersebut."
 
 #: src/settings_translation_file.cpp
 msgid "Field of view"
@@ -3386,7 +3481,6 @@ msgid "Filmic tone mapping"
 msgstr "Pemetaan tona sinematik"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3399,7 +3493,8 @@ msgstr ""
 "atau\n"
 "terang pada tekstur lut sinar. Guna penapisan ini untuk membersihkan tekstur "
 "tersebut\n"
-"ketika ia sedang dimuatkan."
+"ketika ia sedang dimuatkan. Ini dibolehkan secara automatik jika pemetaan "
+"mip dibolehkan."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3491,12 +3586,16 @@ msgid "Font size"
 msgstr "Saiz fon"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
-msgstr "Saiz fon bagi fon lalai dalan unit titik (pt)."
+msgid "Font size divisible by"
+msgstr "Saiz fon boleh dibahagikan dengan"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr "Saiz fon bagi fon monospace dalam unit titik (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Saiz fon bagi fon lalai di mana 1 unit = 1 piksel pada 96 DPI"
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Saiz fon bagi fon monospace di mana 1 unit = 1 piksel pada 96 DPI"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3506,6 +3605,25 @@ msgstr ""
 "Saiz fon tulisan sembang baru-baru ini dan prom dalam unit titik (pt).\n"
 "Nilai 0 akan menggunakan saiz fon lalai."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+"Untuk fon gaya piksel yang tidak boleh disesuaikan dengan baik, tetapan ini "
+"memastikan saiz fon\n"
+"yang digunakan dengan fon ini akan sentiasa boleh dibahagikan dengan nilai "
+"ini, dalam piksel.\n"
+"Contohnya, sebuah fon piksel dengan tinggi 16 piksel patut tetapkan tetapan "
+"ini menjadi 16, supaya\n"
+"ia hanya guna saiz 16, 32, 48, dll., jadi jika mods meminta fon bersaiz 25 "
+"maka ia akan dapat saiz 32."
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3569,11 +3687,7 @@ msgstr "Jenis fraktal"
 
 #: src/settings_translation_file.cpp
 msgid "Fraction of the visible distance at which fog starts to be rendered"
-msgstr "Bahagian daripada jarak boleh lihat di mana kabut mula dijana"
-
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Fon FreeType"
+msgstr "Bahagian daripada jarak boleh lihat di mana kabut mula dikemas gabung"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3636,10 +3750,10 @@ msgstr "Panggil balik sejagat"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Atribut penjanaan peta sejagat.\n"
-"Dalam janapeta v6, bendera 'decorations' mengawal semua hiasan kecuali "
+"Dalam Janapeta v6, bendera 'decorations' mengawal semua hiasan kecuali "
 "pokok\n"
 "dan rumput hutan, dalam janapeta lain pula bendera ini mengawal semua hiasan."
 
@@ -3724,10 +3838,9 @@ msgid "Heat noise"
 msgstr "Hingar haba"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Komponen tinggi saiz tetingkap awal."
+msgstr "Komponen tinggi saiz tetingkap awal. Diabaikan dalam mod skrin penuh."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3935,7 +4048,7 @@ msgid ""
 "If negative, liquid waves will move backwards.\n"
 "Requires waving liquids to be enabled."
 msgstr ""
-"Secepat mana gelora cecair akan bergerak. Nilai tinggi = lebih laju.\n"
+"Secepat mana gelora cecair akan bergerak. Nilai tinggi = lebih cepat.\n"
 "Jika nilai negatif, gelora cecair akan bergerak ke belakang.\n"
 "Memerlukan tetapan cecair bergelora dibolehkan."
 
@@ -3982,12 +4095,11 @@ msgstr ""
 "tidurkannya supaya tidak bazirkan kuasa CPU dengan sia-sia."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Jika dilumpuhkan, kekunci \"istimewa\" akan digunakan untuk terbang laju\n"
+"Jika dilumpuhkan, kekunci \"Aux1\" akan digunakan untuk terbang laju\n"
 "sekiranya kedua-dua mod terbang dan mod pergerakan pantas dibolehkan."
 
 #: src/settings_translation_file.cpp
@@ -4014,15 +4126,13 @@ msgstr ""
 "Ini memerlukan keistimewaan \"tembus blok\" dalam pelayan tersebut."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Jika dibolehkan, kekunci \"istimewa\" akan digunakan untuk panjat ke bawah "
-"dan\n"
-"turun dalam mod terbang, menggantikan kekunci \"selinap\"."
+"Jika dibolehkan, kekunci \"Aux1\" akan digunakan untuk panjat ke bawah dan\n"
+"turun dalam mod terbang, menggantikan kekunci \"Selinap\"."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4084,6 +4194,10 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Jika pelaksanaan sesuatu perintah sembang mengambil masa lebih lama daripada "
+"yang\n"
+"dinyatakan di sini dalam unit saat, tambah maklumat masa ke mesej perintah "
+"sembang"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4100,7 +4214,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid "If this is set, players will always (re)spawn at the given position."
 msgstr ""
-"Jika tetapan ini ditetapkan, pemain akan sentiasa dilahirkan (semula) dekat "
+"Jika tetapan ini ditetapkan, pemain akan sentiasa jelma (semula) dekat "
 "kedudukan yang diberikan."
 
 #: src/settings_translation_file.cpp
@@ -4144,7 +4258,7 @@ msgstr ""
 "Ini selalunya hanya diperlukan oleh penyumbang teras/terbina dalam"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr "Memasang perintah sembang ketika pendaftaran."
 
 #: src/settings_translation_file.cpp
@@ -4236,7 +4350,7 @@ msgid "Joystick button repetition interval"
 msgstr "Selang masa pengulangan butang kayu bedik"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Zon mati kayu bedik"
 
 #: src/settings_translation_file.cpp
@@ -4459,7 +4573,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Kekunci untuk membuka tetingkap sembang untuk menaip arahan.\n"
+"Kekunci untuk membuka tetingkap sembang untuk menaip perintah.\n"
 "Lihat http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -4469,7 +4583,7 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
-"Kekunci untuk membuka tetingkap sembang untuk menaip arahan tempatan.\n"
+"Kekunci untuk membuka tetingkap sembang untuk menaip perintah tempatan.\n"
 "Lihat http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 
@@ -5233,7 +5347,7 @@ msgid ""
 "Useful for mod developers and server operators."
 msgstr ""
 "Memuatkan pembukah permainan untuk mengutip data pemprofilan permainan.\n"
-"Menyediakan perintah /profiler untuk mengakses profil yang dikompil.\n"
+"Menyediakan perintah /profiler untuk mencapai profil yang dikompil.\n"
 "Berguna untuk pembangun mods dan pengendali pelayan."
 
 #: src/settings_translation_file.cpp
@@ -5350,9 +5464,8 @@ msgid "Map save interval"
 msgstr "Selang masa penyimpanan peta"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Detik kemas kini cecair"
+msgid "Map shadows update frames"
+msgstr "Bingkai kemas kini bayang peta"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5466,7 +5579,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Jarak maksimum untuk mengemas gabung bayang."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5541,7 +5654,7 @@ msgid ""
 "Maximum number of mapblocks for client to be kept in memory.\n"
 "Set to -1 for unlimited amount."
 msgstr ""
-"Jumlah blok peta maksimum yang klien boleh simpan dalam memori.\n"
+"Jumlah blok peta maksimum yang klien boleh simpan dalam ingatan.\n"
 "Tetapkan kepada -1 untuk jumlah tanpa had."
 
 #: src/settings_translation_file.cpp
@@ -5597,18 +5710,20 @@ msgstr ""
 "had."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Masa maksimum dalam unit ms untuk muat turun fail (cth. muat turun mods)."
+"Masa maksimum yang dibenarkan untuk muat turun fail (cth. muat turun mods), "
+"dalam unit milisaat."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Masa maksimum yang dibenarkan untuk permintaan saling tindak (cth. mengambil "
+"senarai pelayan), dalam unit milisaat."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5671,8 +5786,8 @@ msgid "Mod channels"
 msgstr "Saluran mods"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "Mengubah saiz elemen palang papar pandu (hudbar)."
+msgid "Modifies the size of the HUD elements."
+msgstr "Mengubah saiz elemen papar pandu (HUD)."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
@@ -5682,6 +5797,10 @@ msgstr "Laluan fon monospace"
 msgid "Monospace font size"
 msgstr "Saiz fon monospace"
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr "Saiz fon monospace boleh dibahagikan dengan"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Hingar ketinggian gunung"
@@ -5799,7 +5918,7 @@ msgstr "Hingar"
 
 #: src/settings_translation_file.cpp
 msgid "Number of emerge threads"
-msgstr "Jumlah jalur keluar"
+msgstr "Jumlah jalur timbul"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5832,13 +5951,13 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Jumlah blok-blok tambahan yang boleh dimuatkan oleh /clearobjects pada "
 "sesuatu masa.\n"
-"Ini merupakan keseimbangan antara overhed urus niaga sqlite\n"
-"dan penggunaan memori (Kebiasaannya, 4096=100MB)."
+"Ini merupakan keseimbangan antara overhed urus niaga SQLite\n"
+"dan penggunaan ingatan (4096=100MB, mengikut kebiasaan)."
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
@@ -5862,18 +5981,17 @@ msgstr ""
 "Buka menu jeda apabila fokus tetingkap hilang.\n"
 "Tidak jeda jika formspec dibuka."
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Pilihan mengatasi warna pautan sesawang di sembang."
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
-"Laluan fon berbalik.\n"
-"Jika tetapan “freetype” dibolehkan: Ia mestilah fon TrueType.\n"
-"Jika tetapan “freetype” dilumpuhkan: Ia mestilah fon peta bit atau vektor "
-"XML.\n"
+"Laluan fon berbalik. Mestilah sebuah fon jenis TrueType.\n"
 "Fon ini akan digunakan bagi sesetengah bahasa atau jika fon lalai tidak "
 "tersedia."
 
@@ -5899,29 +6017,19 @@ msgstr "Laluan ke direktori tekstur. Semua tekstur dicari dari sini dahulu."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
-"Laluan fon lalai.\n"
-"Jika tetapan “freetype” dibolehkan: Ia mestilah fon TrueType.\n"
-"Jika tetapan “freetype” dilumpuhkan: Ia mestilah fon peta bit atau vektor "
-"XML.\n"
+"Laluan fon lalai. Mestilah sebuah fon jenis TrueType.\n"
 "Fon berbalik akan digunakan sekiranya fon ini tidak dapat dimuatkan."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
-"Laluan fon monospace.\n"
-"Jika tetapan “freetype” dibolehkan: Ia mestilah fon TrueType.\n"
-"Jika tetapan “freetype” dilumpuhkan: Ia mestilah fon peta bit atau vektor "
-"XML.\n"
-"Fon ini digunakan untuk unsur spt. konsol dan skrin pembukah."
+"Laluan fon monospace. Mestilah sebuah fon jenis TrueType.\n"
+"Fon ini digunakan untuk perkara spt. konsol dan skrin pembukah."
 
 #: src/settings_translation_file.cpp
 msgid "Pause on lost window focus"
@@ -5976,9 +6084,8 @@ msgid "Player versus player"
 msgstr "Pemain lawan pemain"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Penapisan bilinear"
+msgstr "Penapisan poisson"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6037,12 +6144,12 @@ msgstr "Alamat pendengar Prometheus"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Alamat pendengar Prometheus.\n"
-"Jika minetest dikompil dengan tetapan ENABLE_PROMETHEUS dibolehkan,\n"
+"Jika Minetest dikompil dengan pilihan ENABLE_PROMETHEUS dibolehkan,\n"
 "membolehkan pendengar metrik untuk Prometheus pada alamat berkenaan.\n"
 "Metrik boleh diambil di http://127.0.0.1:30000/metrics"
 
@@ -6118,7 +6225,7 @@ msgid ""
 "csm_restriction_noderange)\n"
 "READ_PLAYERINFO: 32 (disable get_player_names call client-side)"
 msgstr ""
-"Hadkan akses sesetengah fungsi pihak klien di pelayan.\n"
+"Hadkan capaian sesetengah fungsi pihak klien di pelayan.\n"
 "Gabungkan bendera bait di bawah ini untuk mengehadkan ciri-ciri pihak klien, "
 "atau\n"
 "tetapkan kepada 0 untuk tiada had:\n"
@@ -6319,7 +6426,7 @@ msgstr ""
 "6 = Set Julia \"Sepupu Mandy\" 4D.\n"
 "7 = Set Mandelbrot \"Variasi\" 4D.\n"
 "8 = Set Julia \"Variasi\" 4D.\n"
-"9 = Set Mandelbrot \"Mandelbrot/Mandelbar\" 3D.\n"
+"9 = Set Mandelbrot jenis \"Mandelbrot/Mandelbar\" 3D.\n"
 "10 = Set Julia \"Mandelbrot/Mandelbar\" 3D.\n"
 "11 = Set Mandelbrot \"Pokok Krismas\" 3D.\n"
 "12 = Set Julia \"Pokok Krismas\" 3D.\n"
@@ -6383,36 +6490,37 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Menetapkan kekuatan bayang.\n"
+"Nilai lebih rendah untuk bayang lebih terang, nilai lebih tinggi untuk "
+"bayang lebih gelap."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Menetapkan saiz jejari bayang lembut.\n"
+"Nilai lebih rendah untuk bayang lebih tajam, nilai lebih tinggi untuk bayang "
+"lebih lembut.\n"
+"Nilai minimum: 1.0; nilai maksimum: 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Menetapkan kecondongan orbit Matahari/Bulan dalam unit darjah.\n"
+"Nilai 0 untuk tidak condong / tiada orbit menegak.\n"
+"Nilai minimum: 0.0; nilai maksimum: 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Tetapkan kepada \"true\" untuk membolehkan daun bergoyang.\n"
+"Tetapkan kepada \"true\" untuk membolehkan Pemetaan Bayang.\n"
 "Memerlukan pembayang untuk dibolehkan."
 
 #: src/settings_translation_file.cpp
@@ -6445,6 +6553,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Menetapkan kualiti tekstur bayang kepada 32 bit.\n"
+"Jika tetapkan kepada \"false\", tekstur 16 bit akan digunakan.\n"
+"Tetapan ini boleh menyebabkan lebih banyak artifak pada bayang."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6462,22 +6573,21 @@ msgstr ""
 "Namun ia hanya berfungsi dengan pembahagian belakang video OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Kualiti tangkap layar"
+msgstr "Kualiti penapisan bayang"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
 msgstr ""
+"Jarak maksimum peta bayang untuk mengemas gabung bayang, dalam unit nod"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Tekstur peta bayang dalam 32 bit"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Saiz tekstur minimum"
+msgstr "Saiz tekstur peta bayang"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6489,7 +6599,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Kekuatan bayang"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6512,7 +6622,7 @@ msgstr ""
 "Anda perlu mulakan semula selepas mengubah tetapan ini."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr "Tunjuk latar belakang tag nama secara lalainya"
 
 #: src/settings_translation_file.cpp
@@ -6547,7 +6657,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Kecondongan Orbit Badan Angkasa"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6610,9 +6720,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Kelajuan menyelinap, dalam unit nod per saat."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Nilai alfa bayang fon"
+msgstr "Jejari bayang lembut"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6626,7 +6735,7 @@ msgid ""
 "Files that are not present will be fetched the usual way."
 msgstr ""
 "Menetapkan URL dari mana klien mengambil media, menggantikan UDP.\n"
-"$filename mestilah boleh diakses daripada $remote_media$filename melalui\n"
+"$filename mestilah boleh dicapai daripada $remote_media$filename melalui\n"
 "cURL (sudah tentu, remote_media mesti berakhir dengan tanda condong).\n"
 "Fail yang tidak wujud akan diambil dengan cara biasa."
 
@@ -6640,6 +6749,18 @@ msgstr ""
 "Ambil perhatian bahawa mods atau permainan boleh tetapkan secara khusus "
 "tindanan untuk sesetengah (atau semua) item."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Sebar kemas kini lengkap peta bayang merentasi jumlah bingkai yang diberi.\n"
+"Nilai lebih tinggi mungkin membuatkan bayang lembap bertindak balas,\n"
+"nilai lebih rendah akan memakan lebih banyak sumber.\n"
+"Nilai minimum: 1; nilai maksimum: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6652,7 +6773,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Static spawnpoint"
-msgstr "Titik lahir statik"
+msgstr "Titik jelma statik"
 
 #: src/settings_translation_file.cpp
 msgid "Steepness noise"
@@ -6779,8 +6900,11 @@ msgstr "Laluan tekstur"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Saiz tekstur yang akan digunakan untuk mengemas gabung peta bayang.\n"
+"Nilai ini mestilah hasil kuasa dua.\n"
+"Nombor lebih besar mencipta bayang lebih baik tetapi ia juga lebih berat."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6806,7 +6930,7 @@ msgid "The URL for the content repository"
 msgstr "URL untuk repositori kandungan"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "Zon mati bagi kayu bedik yang digunakan"
 
 #: src/settings_translation_file.cpp
@@ -6872,7 +6996,7 @@ msgid ""
 "maintained.\n"
 "This should be configured together with active_object_send_range_blocks."
 msgstr ""
-"Radius jilid blok di sekitar setiap pemain yang tertakluk kepada benda blok\n"
+"Jejari jilid blok di sekitar setiap pemain yang tertakluk kepada benda blok\n"
 "aktif, dinyatakan dalam blokpeta (16 nod).\n"
 "Dalam blok aktif, objek dimuatkan dan ABM dijalankan.\n"
 "Ini juga jarak minimum di mana objek aktif (mob) dikekalkan.\n"
@@ -6880,7 +7004,6 @@ msgstr ""
 "(active_object_send_range_blocks)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6889,7 +7012,7 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Terjemahan bahagian belakang untuk Irrlicht.\n"
+"Kemas gabung bahagian belakang.\n"
 "Anda perlu memulakan semula selepas mengubah tetapan ini.\n"
 "Nota: Di Android, kekalkan dengan OGLES1 jika tidak pasti! Apl mungkin gagal "
 "dimulakan jika ditukar.\n"
@@ -6899,7 +7022,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Kepekaan paksi kayu bedik untuk menggerakkan\n"
 "frustum penglihatan dalam permainan."
@@ -6976,7 +7099,8 @@ msgid ""
 "Time in seconds for item entity (dropped items) to live.\n"
 "Setting it to -1 disables the feature."
 msgstr ""
-"Masa untuk entiti item (item yang dijatuhkan) terus hidup dalam unit saat.\n"
+"Masa untuk entiti item (iaitu item yang dijatuhkan) terus hidup dalam unit "
+"saat.\n"
 "Tetapkan kepada -1 untuk melumpuhkan sifat tersebut."
 
 #: src/settings_translation_file.cpp
@@ -6994,7 +7118,7 @@ msgstr "Kelajuan masa"
 
 #: src/settings_translation_file.cpp
 msgid "Timeout for client to remove unused map data from memory."
-msgstr "Had masa untuk klien membuang peta yang tidak digunakan dari memori."
+msgstr "Had masa untuk klien membuang peta yang tidak digunakan dari ingatan."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7020,6 +7144,10 @@ msgstr "Lengah tip alatan"
 msgid "Touch screen threshold"
 msgstr "Nilai ambang skrin sentuh"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "Keseimbangan untuk prestasi"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Hingar pokok"
@@ -7099,12 +7227,12 @@ msgstr "Gunakan penapisan bilinear apabila menyesuaikan tekstur."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
 "Gunakan pemetaan mip untuk menyesuaikan tekstur. Boleh meningkatkan\n"
-"sedikit prestasi, terutamanya apabila menggunakan pek tekstur berdefinisi\n"
+"sedikit prestasi, terutamanya apabila menggunakan pek tekstur resolusi\n"
 "tinggi. Penyesuai-turun gama secara tepat tidak disokong."
 
 #: src/settings_translation_file.cpp
@@ -7136,7 +7264,7 @@ msgstr "VBO"
 
 #: src/settings_translation_file.cpp
 msgid "VSync"
-msgstr "VSync"
+msgstr "Segerak Menegak"
 
 #: src/settings_translation_file.cpp
 msgid "Valley depth"
@@ -7228,9 +7356,8 @@ msgid "Viewing range"
 msgstr "Jarak pandang"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Kayu bedik maya memicu butang aux"
+msgstr "Kayu bedik maya memicu butang Aux1"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7308,6 +7435,10 @@ msgstr "Panjang ombak cecair bergelora"
 msgid "Waving plants"
 msgstr "Tumbuhan bergoyang"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Warna pautan sesawang"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7318,8 +7449,7 @@ msgstr ""
 "semua\n"
 "imej GUI perlu ditapis dalam perisian, tetapi sesetengah imej dijana secara "
 "terus\n"
-"ke perkakasan (contohnya, penterjemahan-ke-tekstur untuk nod dalam "
-"inventori)."
+"ke perkakasan (contohnya, kemas-gabung-ke-tekstur untuk nod dalam inventori)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7338,49 +7468,38 @@ msgstr ""
 "perkakasan."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
 msgstr ""
 "Apabila menggunakan tapisan bilinear/trilinear/anisotropik, tekstur "
 "resolusi\n"
-"rendah boleh jadi kabur, jadi sesuai-naikkan mereka secara automatik dengan\n"
-"sisipan jiran terdekat untuk memelihara piksel keras. Tetapan ini "
-"menetapkan\n"
-"saiz tekstur minima untuk tekstur penyesuai-naikkan; nilai lebih tinggi "
-"tampak\n"
-"lebih tajam, tetapi memerlukan memori yang lebih banyak.  Nilai kuasa 2\n"
-"digalakkan.  Menetapkan nilai ini lebih tinggi dari 1 tidak akan "
-"menampakkan\n"
-"kesan yang nyata melainkan tapisan bilinear/trilinear/anisotropik "
+"rendah boleh jadi kabur, jadi sesuai-naikkannya secara automatik dengan "
+"sisipan\n"
+"jiran terdekat untuk memelihara piksel keras. Tetapan ini menetapkan saiz "
+"tekstur\n"
+"minimum untuk tekstur yang disesuai-naikkan; nilai lebih tinggi tampak "
+"lebih\n"
+"tajam, tetapi memerlukan ingatan yang lebih banyak. Nilai kuasa 2 "
+"digalakkan.\n"
+"Tetapan ini HANYA digunakan jika penapisan bilinear/trilinear/anisotropik "
 "dibolehkan.\n"
-"Ini juga digunakan sebagai saiz tekstur nod asas untuk autopenyesuaian\n"
-"tekstur jajaran dunia."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Menetapkan sama ada fon FreeType digunakan, memerlukan sokongan Freetype\n"
-"dikompil bersama. Jika dilumpuhkan, fon peta bit dan vektor XML akan "
-"digunakan."
+"Tetapan ini juga digunakan sebagai saiz tekstur nod asas untuk\n"
+"penyesuaian automatik bagi tekstur jajaran dunia."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 "Sama ada latar belakang tag nama patut ditunjukkan secara lalainya.\n"
-"Mods masih boleh tetapkan latar belakang."
+"Mods masih boleh menetapkan latar belakang."
 
 #: src/settings_translation_file.cpp
 msgid "Whether node texture animations should be desynchronized per mapblock."
@@ -7435,9 +7554,8 @@ msgstr ""
 "seperti menekan butang F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Komponen lebar saiz tetingkap awal."
+msgstr "Komponen lebar saiz tetingkap awal. Diabaikan dalam mod skrin penuh."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7539,48 +7657,24 @@ msgstr "Aras Y untuk rupa bumi lebih rendah dan dasar laut."
 msgid "Y-level of seabed."
 msgstr "Aras Y untuk dasar laut."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Tahap pemampatan ZLib untuk digunakan apabila menyimpan blokpeta ke cakera.\n"
-"-1 - tahap pemampatan lalai Zlib\n"
-"0 - tiada pemampatan, paling laju\n"
-"9 - pemampatan terbaik, paling lambat\n"
-"(tahap 1-3 menggunakan kaedah \"fast\" Zlib, 4-9 menggunakan kaedah biasa)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Tahap pemampatan ZLib untuk digunakan apabila menghantar blokpeta kepada "
-"klien.\n"
-"-1 - tahap pemampatan lalai Zlib\n"
-"0 - tiada pemampatan, paling laju\n"
-"9 - pemampatan terbaik, paling lambat\n"
-"(tahap 1-3 menggunakan kaedah \"fast\" Zlib, 4-9 menggunakan kaedah biasa)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Had masa muat turun fail cURL"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "Had masa cURL"
+msgstr "Had masa saling tindak cURL"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "Had cURL selari"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Mod Kreatif: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Boleh cedera: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7762,6 +7856,9 @@ msgstr "Had cURL selari"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Saiz fon bagi fon berbalik dalam unit titik (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Fon FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP skrin penuh"
 
@@ -7780,6 +7877,9 @@ msgstr "Had cURL selari"
 #~ msgid "IPv6 support."
 #~ msgstr "Sokongan IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Pasang: fail: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Kedalaman lava"
 
@@ -7885,6 +7985,17 @@ msgstr "Had cURL selari"
 #~ msgid "Select Package File:"
 #~ msgstr "Pilih Fail Pakej:"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "Menetapkan masa kemas kini bayang.\n"
+#~ "Nilai lebih rendah untuk kemas kini peta dan bayang lebih laju, tetapi "
+#~ "menggunakan lebih banyak sumber.\n"
+#~ "Nilai minimum 0.001 saat dan nilai maksimum 0.2 saat"
+
 #~ msgid "Shadow limit"
 #~ msgstr "Had bayang"
 
@@ -7913,6 +8024,9 @@ msgstr "Had cURL selari"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Fon ini akan digunakan untuk sesetengah bahasa."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Untuk membolehkan pembayang, pemacu OpenGL mesti digunakan."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Togol Sinematik"
 
@@ -7936,6 +8050,15 @@ msgstr "Had cURL selari"
 #~ msgid "Waving water"
 #~ msgstr "Air bergelora"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Menetapkan sama ada fon FreeType digunakan, memerlukan sokongan Freetype\n"
+#~ "dikompil bersama. Jika dilumpuhkan, fon peta bit dan vektor XML akan "
+#~ "digunakan."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr ""
 #~ "Sama ada kurungan bawah tanah kadang-kala terlunjur daripada rupa bumi."
@@ -7952,5 +8075,8 @@ msgstr "Had cURL selari"
 #~ msgid "Yes"
 #~ msgstr "Ya"
 
+#~ msgid "You died."
+#~ msgstr "Anda telah meninggal."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 20e3d1120b597384f73162250ad26905ac299acb..4924cf7b4fa1596060f0a1523ce701164b73a398 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2020-10-20 18:26+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-10 23:53+0000\n"
 "Last-Translator: Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat "
 "Yasuyoshi <translation@mnh48.moe>\n"
 "Language-Team: Malay (Jawi) <https://hosted.weblate.org/projects/minetest/"
@@ -18,7 +18,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.3.1\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
 #, fuzzy
@@ -69,11 +69,6 @@ msgstr "لاهير سمولا"
 msgid "You died"
 msgstr "اندا تله منيڠݢل"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "اندا تله منيڠݢل"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -105,6 +100,10 @@ msgstr ""
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "برلاکوڽ رالت دالم سکريڤ Lua:"
@@ -310,6 +309,11 @@ msgstr "ڤاسڠ"
 msgid "Install missing dependencies"
 msgstr "کبرݢنتوڠن ڤيليهن:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "ڤاسڠ: جنيس فايل \"$1\" تيدق دسوکوڠ اتاو ارکيب روسق"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -641,7 +645,8 @@ msgid "Offset"
 msgstr "اوفسيت"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "ڤنروسن"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -751,14 +756,6 @@ msgstr "ڤاسڠ مودس: ݢاݢل منچاري نام مودس سبنر اون
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "ڤاسڠ مودس: تيدق جومڤ نام فولدر يڠ سسواي اونتوق ڤيک مودس $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "ڤاسڠ: جنيس فايل \"$1\" تيدق دسوکوڠ اتاو ارکيب روسق"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "ڤاسڠ: فايل: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "تيدق جومڤ مودس اتاو ڤيک مودس يڠ صح"
@@ -1134,10 +1131,6 @@ msgstr "ڤنچهاياٴن لمبوت"
 msgid "Texturing:"
 msgstr "جالينن:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "اونتوق ممبوليهکن ڤمبايڠ⹁ ڤماچو OpenGL مستي دݢوناکن."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "ڤمتاٴن تونا"
@@ -1170,7 +1163,7 @@ msgstr "چچاٴير برݢلورا"
 msgid "Waving Plants"
 msgstr "تومبوهن برݢويڠ"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "سمبوڠن تامت تيمڤوه."
 
@@ -1199,7 +1192,8 @@ msgid "Connection error (timed out?)"
 msgstr "رالت دالم ڤڽمبوڠن (تامت تيمڤوه؟)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "تيدق جومڤ اتاو تيدق بوليه مواتکن ڤرماٴينن \""
 
 #: src/client/clientlauncher.cpp
@@ -1242,14 +1236,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- علامت: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- مود کرياتيف: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- بوليه چدرا "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- مود: "
@@ -1271,6 +1257,16 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- نام ڤلاين: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "تله برلاکوڽ رالت:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "ڤرݢرقن اٴوتوماتيک دلومڤوهکن"
@@ -1279,6 +1275,22 @@ msgstr "ڤرݢرقن اٴوتوماتيک دلومڤوهکن"
 msgid "Automatic forward enabled"
 msgstr "ڤرݢرقن اٴوتوماتيک دبوليهکن"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "کمس کيني کاميرا دلومڤوهکن"
@@ -1287,6 +1299,10 @@ msgstr "کمس کيني کاميرا دلومڤوهکن"
 msgid "Camera update enabled"
 msgstr "کمس کيني کاميرا دبوليهکن"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "توکر کات لالوان"
@@ -1299,6 +1315,11 @@ msgstr "مود سينماتيک دلومڤوهکن"
 msgid "Cinematic mode enabled"
 msgstr "مود سينماتيک دبوليهکن"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "مودس کليئن"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "سکريڤ ڤيهق کليئن دلومڤوهکن"
@@ -1307,6 +1328,10 @@ msgstr "سکريڤ ڤيهق کليئن دلومڤوهکن"
 msgid "Connecting to server..."
 msgstr "سدڠ مڽمبوڠ کڤد ڤلاين..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "تروسکن"
@@ -1344,6 +1369,11 @@ msgstr ""
 "- رودا تتيکوس: ڤيليه ايتم\n"
 "- %s: سيمبڠ\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "سدڠ منچيڤت کليئن..."
@@ -1549,6 +1579,21 @@ msgstr "سيستم بوڽي تيدق دسوکوڠ دبيناٴن اين"
 msgid "Sound unmuted"
 msgstr "بوڽي دڽهبيسوکن"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1884,6 +1929,15 @@ msgstr "ڤتا ميني دالم مود ڤرموکاٴن⹁ زوم 1x"
 msgid "Minimap in texture mode"
 msgstr "سايز تيکستور مينيموم"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "ݢاݢل مموات تورون $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "کات لالوان تيدق ڤادن!"
@@ -2085,7 +2139,8 @@ msgid "Muted"
 msgstr "دبيسوکن"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "ککواتن بوڽي: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2324,6 +2379,10 @@ msgstr ""
 "لارسکن کونفيݢوراسي DPI کسکرين اندا (بوکن X11/Android سهاج) چونتوه اونتوق "
 "سکرين 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2606,6 +2665,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "نيلاي امبڠ تندڠ ميسيج سيمبڠ"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "ارهن"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "سايز فون سيمبڠ"
@@ -2639,8 +2703,9 @@ msgid "Chat toggle key"
 msgstr "ککونچي توݢول سيمبڠ"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "سيمبڠ دتونجوقکن"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2658,6 +2723,12 @@ msgstr "ککونچي مود سينماتيک"
 msgid "Clean transparent textures"
 msgstr "برسيهکن تيکستور لوت سينر"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "کليئن"
@@ -2734,6 +2805,22 @@ msgstr ""
 msgid "Command key"
 msgstr "ککونچي ارهن"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "سمبوڠ کاچ"
@@ -2832,7 +2919,7 @@ msgstr "نيلاي الفا ررمبوت سيلڠ"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr "نيلاي الفا ررمبوت سيلڠ (کلݢڤن⹁ انتارا 0 دان 255)."
 
 #: src/settings_translation_file.cpp
@@ -2911,8 +2998,8 @@ msgstr "ساٴيز تيندنن لالاي"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3038,6 +3125,10 @@ msgstr "ملومڤوهکن انتيتيڤو"
 msgid "Disallow empty passwords"
 msgstr "منولق کات لالوان کوسوڠ"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "نام دوماٴين ڤلاين ڤرماٴينن⹁ اونتوق دڤاڤرکن دالم سناراي ڤلاين ڤرماٴينن."
@@ -3086,7 +3177,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3115,13 +3213,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr "ممبوليهکن ڤماٴين منريما کچدراٴن دان ماتي."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "ممبوليهکن اينڤوت ڤڠݢونا سچارا راوق (هاڽ اونتوق ڤرچوباٴن)."
@@ -3234,6 +3325,12 @@ msgstr ""
 "دان کاولن بوڽي دالم ڤرماٴينن تيدق اکن برفوڠسي.\n"
 "ڤڠوبهن تتڤن اين ممرلوکن ڤرمولاٴن سمولا."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3429,11 +3526,17 @@ msgid "Font size"
 msgstr "سايز فون"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "سايز فون باݢي فون لالاي دالم اونيت تيتيق (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "سايز فون باݢي فون monospace دالم اونيت تيتيق (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3444,6 +3547,17 @@ msgstr ""
 "سايز فون توليسن سيمبڠ بارو٢ اين دان ڤروم دالم اونيت تيتيق (pt).\n"
 "نيلاي 0 اکن مڠݢوناکن سايز فون لالاي."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3506,10 +3620,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "بهاݢين درڤد جارق بوليه ليهت دمان کابوت مولا دجان"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "فون FreeType"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3564,7 +3674,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3846,7 +3956,7 @@ msgid ""
 "If negative, liquid waves will move backwards.\n"
 "Requires waving liquids to be enabled."
 msgstr ""
-"سچڤت مان ݢلورا چچاٴير اکن برݢرق. نيلاي تيڠݢي = لبيه لاجو.\n"
+"سچڤت مان ݢلورا چچاٴير اکن برݢرق. نيلاي تيڠݢي = لبيه چڤت.\n"
 "جيک نيلاي نيݢاتيف⹁ ݢلورا چچاٴير اکن برݢرق کبلاکڠ.\n"
 "ممرلوکن تتڤن چچاٴير برݢلورا دبوليهکن."
 
@@ -4028,7 +4138,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4114,7 +4224,7 @@ msgstr "سلڠ ماس ڤڠاولڠن بوتڠ کايو بديق"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "جنيس کايو بديق"
 
 #: src/settings_translation_file.cpp
@@ -5168,7 +5278,7 @@ msgid "Map save interval"
 msgstr "سلڠ ماس ڤڽيمڤنن ڤتا"
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5476,7 +5586,8 @@ msgid "Mod channels"
 msgstr "سالوران مودس"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "مڠاوبه سايز ايليمن ڤالڠ ڤاڤر ڤندو (hudbar)."
 
 #: src/settings_translation_file.cpp
@@ -5487,6 +5598,11 @@ msgstr "لالوان فون monospace"
 msgid "Monospace font size"
 msgstr "سايز فون monospace"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "سايز فون monospace"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5614,7 +5730,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5641,10 +5757,13 @@ msgstr ""
 "تيدق جيدا جيک فورمسڤيک دبوک."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5674,10 +5793,9 @@ msgid "Path to texture directory. All textures are first searched from here."
 msgstr "لالوان کديريکتوري تيکستور. سموا تيکستور دچاري دري سيني داهولو."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "لالوان فون لالاي.\n"
@@ -5686,10 +5804,9 @@ msgstr ""
 "فون برباليق اکن دݢوناکن سکيراڽ فون اين تيدق داڤت دمواتکن."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "لالوان فون monospace.\n"
@@ -5805,11 +5922,12 @@ msgid "Prometheus listener address"
 msgstr "علامت ڤندڠر Prometheus"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "علامت ڤندڠر Prometheus.\n"
 "جک minetest دکومڤيل دڠن تتڤن ENABLE_PROMETHEUS دبوليهکن,\n"
@@ -6118,26 +6236,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6244,7 +6354,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr "فون تبل سچارا لالايڽ"
 
 #: src/settings_translation_file.cpp
@@ -6364,6 +6474,14 @@ msgstr ""
 "امبيل ڤرهاتيان بهاوا مودس اتاو ڤرماٴينن بوليه تتڤکن سچارا خصوص تيندنن اونتوق "
 "سستڠه (اتاو سموا) ايتم."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6480,7 +6598,7 @@ msgstr "لالوان تيکستور"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6505,7 +6623,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "ڤڠنل ڤستي کايو بديق يڠ دݢوناکن"
 
 #: src/settings_translation_file.cpp
@@ -6592,9 +6710,10 @@ msgstr ""
 "دان اي اياله ساتو-ساتوڽ ڤماچو يڠ ممڤوڽاٴي سوکوڠن ڤمبايڠ کتيک اين."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "کڤيکاٴن ڤکسي کايو بديق اونتوق مڠݢرقکن\n"
 "فروستوم ڤڠليهتن دالم ڤرماٴينن."
@@ -6704,6 +6823,10 @@ msgstr "لڠه تيڤ التن"
 msgid "Touch screen threshold"
 msgstr "نيلاي امبڠ سکرين سنتوه"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6780,8 +6903,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "ݢوناکن ڤناڤيسن بيلينيار اڤابيلا مڽسوايکن تيکستور."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6970,6 +7094,11 @@ msgstr "ڤنجڠ اومبق چچاٴير برݢلورا"
 msgid "Waving plants"
 msgstr "تومبوهن برݢويڠ"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "ورنا کوتق ڤميليهن"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7000,7 +7129,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7017,16 +7146,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"منتڤکن سام اد فون FreeType دݢوناکن⹁ ممرلوکن سوکوڠن Freetype\n"
-"دکومڤيل برسام. جيک دلومڤوهکن⹁ فون ڤتا بيت دان ۏيکتور XML اکن دݢوناکن."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7174,24 +7294,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -7204,6 +7306,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- مود کرياتيف: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- بوليه چدرا "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7294,6 +7402,9 @@ msgstr ""
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "سايز فون باݢي فون برباليق دالم اونيت تيتيق (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "فون FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP سکرين ڤنوه"
 
@@ -7303,6 +7414,9 @@ msgstr ""
 #~ msgid "Generate normalmaps"
 #~ msgstr "جان ڤتا نورمل"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "ڤاسڠ: فايل: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "اوتام"
 
@@ -7390,11 +7504,26 @@ msgstr ""
 #~ msgid "Strength of generated normalmaps."
 #~ msgstr "ککواتن ڤتا نورمل يڠ دجان."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "اونتوق ممبوليهکن ڤمبايڠ⹁ ڤماچو OpenGL مستي دݢوناکن."
+
 #~ msgid "View"
 #~ msgstr "ليهت"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "منتڤکن سام اد فون FreeType دݢوناکن⹁ ممرلوکن سوکوڠن Freetype\n"
+#~ "دکومڤيل برسام. جيک دلومڤوهکن⹁ فون ڤتا بيت دان ۏيکتور XML اکن دݢوناکن."
+
 #~ msgid "Yes"
 #~ msgstr "ياٴ"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "اندا تله منيڠݢل"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index 2497e570ca289a3229961d2c26ac88a081318132..d550602e607f9df0a376ce3859b88dd67c28cba3 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Norwegian Bokmål (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-05-09 08:57+0000\n"
-"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-10 23:53+0000\n"
+"Last-Translator: Imre Kristoffer Eilertsen <imreeil42@gmail.com>\n"
 "Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/"
 "minetest/minetest/nb_NO/>\n"
 "Language: nb\n"
@@ -12,16 +12,15 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
 msgstr ""
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Sludrekommandoer"
+msgstr "Tom kommando."
 
 #: builtin/client/chatcommands.lua
 #, fuzzy
@@ -35,7 +34,7 @@ msgstr "Lokal kommando"
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Avgitt kommando: "
 
 #: builtin/client/chatcommands.lua
 #, fuzzy
@@ -53,7 +52,7 @@ msgstr ""
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Denne kommandoen er utkoblet av tjeneren."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -63,11 +62,6 @@ msgstr "Gjenoppstå"
 msgid "You died"
 msgstr "Du døde"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Du døde"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -80,7 +74,7 @@ msgstr "Lokal kommando"
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Ikke tilgjengelig kommando: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
@@ -99,6 +93,11 @@ msgstr ""
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Ikke tilgjengelig kommando: "
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Det oppstod en feil i et Lua-skript:"
@@ -234,7 +233,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1 av $2"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
@@ -304,6 +303,11 @@ msgstr "Installer"
 msgid "Install missing dependencies"
 msgstr "Valgfrie avhengigheter:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Installasjon: Ikke-støttet filtype \"$1\" eller ødelagt arkiv"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -318,17 +322,16 @@ msgid "No results"
 msgstr "Resultatløst"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "No updates"
-msgstr "Oppdater"
+msgstr "Ingen oppdateringer"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Not found"
-msgstr ""
+msgstr "Ikke funnet"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
-msgstr ""
+msgstr "Overskriv"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Please check that the base game is correct."
@@ -336,7 +339,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "Satt i kø"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Texture packs"
@@ -633,7 +636,8 @@ msgid "Offset"
 msgstr "Forskyvning"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Bestandighet"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -743,14 +747,6 @@ msgstr "Installer mod: Klarte ikke å finne riktig mod-navn for: $1"
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "Installer mod: Klarte ikke finne egnet mappenavn for mod-pakke $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Installasjon: Ikke-støttet filtype \"$1\" eller ødelagt arkiv"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Installasjon: fil \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Klarte ikke finne en gyldig mod eller modpakke"
@@ -788,7 +784,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Om"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
@@ -892,7 +888,7 @@ msgstr "Installer spill fra ContentDB"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "Navn"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
@@ -903,9 +899,8 @@ msgid "No world created or selected!"
 msgstr "Ingen verden opprettet eller valgt!"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Password"
-msgstr "Nytt passord"
+msgstr "Passord"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
@@ -933,9 +928,8 @@ msgid "Start Game"
 msgstr "Start spill"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adresse: "
+msgstr "Adresse"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -960,9 +954,8 @@ msgid "Del. Favorite"
 msgstr "Slett favoritt"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favoritt"
+msgstr "Favoritter"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
@@ -983,7 +976,7 @@ msgstr "Annonseringstjener"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Oppdater"
 
 #: builtin/mainmenu/tab_online.lua
 #, fuzzy
@@ -1045,15 +1038,15 @@ msgstr "Forseggjorte blader"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Høy"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Lav"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Medium"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1114,7 +1107,7 @@ msgstr "Flytlandene (eksperimentelt)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
-msgstr "Skyggelegging (ikke tilgjenglig)"
+msgstr "Skyggelegging (ikke tilgjengelig)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Simple Leaves"
@@ -1122,16 +1115,12 @@ msgstr "Enkle løv"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Smooth Lighting"
-msgstr "Gjevn belysning"
+msgstr "Jevn belysning"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Texturing:"
 msgstr "Teksturering:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "For å skru på skyggeleging, må man bruke OpenGL-driveren."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Nyanseoversettelse (tone mapping)"
@@ -1146,11 +1135,11 @@ msgstr "Trilineært filter"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Ultrahøy"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Veldig lav"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1164,7 +1153,7 @@ msgstr "Skvulpende væsker"
 msgid "Waving Plants"
 msgstr "Bølgende planter"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Forbindelsen løp ut på tid."
 
@@ -1193,7 +1182,8 @@ msgid "Connection error (timed out?)"
 msgstr "Tilkoblingsfeil (tidsavbrudd?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Klarte ikke finne eller laste inn spill «"
 
 #: src/client/clientlauncher.cpp
@@ -1236,14 +1226,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresse: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kreativ modus: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Skade: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Modus: "
@@ -1265,6 +1247,16 @@ msgstr "- Alle mot alle (PvP): "
 msgid "- Server Name: "
 msgstr "- Tjenernavn: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Det oppstod en feil:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automatisk forover slått av"
@@ -1273,6 +1265,22 @@ msgstr "Automatisk forover slått av"
 msgid "Automatic forward enabled"
 msgstr "Automatisk forover slått på"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kameraoppdatering slått av"
@@ -1281,6 +1289,10 @@ msgstr "Kameraoppdatering slått av"
 msgid "Camera update enabled"
 msgstr "Kameraoppdatering slått på"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Endre passord"
@@ -1293,6 +1305,11 @@ msgstr "Filmatisk modus avskrudd"
 msgid "Cinematic mode enabled"
 msgstr "Filmatisk modus påskrudd"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Brukermodding"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Skripting er slått av på klientside"
@@ -1301,6 +1318,10 @@ msgstr "Skripting er slått av på klientside"
 msgid "Connecting to server..."
 msgstr "Kobler til tjener…"
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Fortsett"
@@ -1338,6 +1359,11 @@ msgstr ""
 "- Musehjul: velg ting\n"
 "- %s: sludring\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Oppretter klient…"
@@ -1348,7 +1374,7 @@ msgstr "Oppretter tjener…"
 
 #: src/client/game.cpp
 msgid "Debug info and profiler graph hidden"
-msgstr "Skjuler feilsøkingsinfo og profilgraf"
+msgstr "Skjuler feilsøkingsinfo og profileringsgraf"
 
 #: src/client/game.cpp
 msgid "Debug info shown"
@@ -1356,7 +1382,7 @@ msgstr "Viser feilsøkingsinfo"
 
 #: src/client/game.cpp
 msgid "Debug info, profiler graph, and wireframe hidden"
-msgstr ""
+msgstr "Skjuler feilsøkingsinfo, profileringsgraf og 3D-gitter"
 
 #: src/client/game.cpp
 msgid ""
@@ -1467,9 +1493,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr ""
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Enkeltspiller"
+msgstr "Flerspiller"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1544,6 +1569,21 @@ msgstr "Lydsystem støttes ikke på dette bygget"
 msgid "Sound unmuted"
 msgstr "Lyd på"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1878,6 +1918,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Klarte ikke laste ned $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Passordene samsvarer ikke!"
@@ -2081,7 +2130,8 @@ msgid "Muted"
 msgstr "Av"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Lydstyrke: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2335,6 +2385,10 @@ msgstr ""
 "Justér skjermens DPI-innstilling (ikke for X11/kun Android), f. eks. for 4k-"
 "skjermer."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2626,6 +2680,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Terskel for utvisning fra chat"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Sludrekommandoer"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2661,8 +2720,9 @@ msgid "Chat toggle key"
 msgstr "Tast for veksling av sludring"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Sludrekommandoer"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Viser chat"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2680,6 +2740,12 @@ msgstr "Tast for filmatisk tilstand"
 msgid "Clean transparent textures"
 msgstr "Rene, gjennomsiktige teksturer"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klient"
@@ -2767,6 +2833,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Tast for chat og kommandoer"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Forbind glass"
@@ -2866,8 +2948,10 @@ msgstr "Trådkors-alpha"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
-msgstr "Trådkors-alpha (ugjennomsiktighet, mellom 0 og 255)."
+"This also applies to the object crosshair."
+msgstr ""
+"Trådkors-alpha (ugjennomsiktighet, mellom 0 og 255).\n"
+"Kontrollerer også objektets trådkorsfarge"
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2944,8 +3028,8 @@ msgstr "Forvalgt spill"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3065,6 +3149,10 @@ msgstr "Skru av antijuksing"
 msgid "Disallow empty passwords"
 msgstr "Ikke tillatt tomme passord"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Domenenavn for tjener, som vist i tjenerlisten."
@@ -3112,7 +3200,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3121,9 +3216,8 @@ msgid "Enable console window"
 msgstr "Skru på konsollvindu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable creative mode for all players"
-msgstr "Skru på kreativt modusfor nye opprettede kart."
+msgstr "Aktiver kreativt modus for alle spillere"
 
 #: src/settings_translation_file.cpp
 msgid "Enable joysticks"
@@ -3141,13 +3235,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3234,6 +3321,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3253,13 +3346,12 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "FPS when unfocused or paused"
-msgstr "Maks FPS når spillet står i pause."
+msgstr "Maks FPS når spillet ikke har fokus eller er pauset"
 
 #: src/settings_translation_file.cpp
 msgid "FSAA"
-msgstr ""
+msgstr "FSAA"
 
 #: src/settings_translation_file.cpp
 msgid "Factor noise"
@@ -3426,11 +3518,15 @@ msgid "Font size"
 msgstr "Skriftstørrelse"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3439,6 +3535,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3498,10 +3605,6 @@ msgstr "Fraktaltype"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "FreeType-skrifttyper"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3550,7 +3653,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3982,7 +4085,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4048,7 +4151,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Iterations"
-msgstr ""
+msgstr "Ringer"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4068,7 +4171,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Spillstikketype"
 
 #: src/settings_translation_file.cpp
@@ -4076,9 +4179,8 @@ msgid "Joystick frustum sensitivity"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Joystick type"
-msgstr "Spillstikketype"
+msgstr "Kontrollertype"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4816,7 +4918,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Language"
-msgstr ""
+msgstr "Språk"
 
 #: src/settings_translation_file.cpp
 msgid "Large cave depth"
@@ -5072,7 +5174,7 @@ msgid "Map save interval"
 msgstr "Lagringsintervall for kart"
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5374,7 +5476,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5385,6 +5487,11 @@ msgstr "Filsti for monospace skrifttype"
 msgid "Monospace font size"
 msgstr "Størrelse for monospace skrifttype"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Størrelse for monospace skrifttype"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5453,7 +5560,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Network"
-msgstr ""
+msgstr "Nettverk"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5506,7 +5613,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5530,11 +5637,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5557,17 +5666,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5664,7 +5769,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Profiling"
-msgstr ""
+msgstr "Profilering"
 
 #: src/settings_translation_file.cpp
 msgid "Prometheus listener address"
@@ -5673,9 +5778,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5849,11 +5954,11 @@ msgstr "Mappe for skjermdumper"
 
 #: src/settings_translation_file.cpp
 msgid "Screenshot format"
-msgstr ""
+msgstr "Skjermklippformat"
 
 #: src/settings_translation_file.cpp
 msgid "Screenshot quality"
-msgstr ""
+msgstr "Skjermklippkvalitet"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5916,6 +6021,25 @@ msgid ""
 "17 = 4D \"Mandelbulb\" Mandelbrot set.\n"
 "18 = 4D \"Mandelbulb\" Julia set."
 msgstr ""
+"Velger en av 18 fraktaltyper.\n"
+"1 = 4D «Rund» Mandelbrot-mengde.\n"
+"2 = 4D «Rund» Julia-mengde.\n"
+"3 = 4D «Firkantet» Mandelbrot-mengde.\n"
+"4 = 4D «Firkantet» Julia-mengde.\n"
+"5 = 4D «Mandy Cousin» Mandelbrot-mengde.\n"
+"6 = 4D «Mandy Cousin» Julia-mengde.\n"
+"7 = 4D «Variasjon» Mandelbrot-mengde.\n"
+"8 = 4D «Variasjon» Julia-mengde.\n"
+"9 = 3D «Mandelbrot/Mandelbar» Mandelbrot-mengde.\n"
+"10 = 3D «Mandelbrot/Mandelbar» Julia-mengde.\n"
+"11 = 3D «Juletre» Mandelbrot-mengde.\n"
+"12 = 3D «Juletre» Julia-mengde.\n"
+"13 = 3D «Mandelbulb» Mandelbrot-mengde.\n"
+"14 = 3D «Mandelbulb» Julia-mengde.\n"
+"15 = 3D «Cosine Mandelbulb» Mandelbrot-mengde.\n"
+"16 = 3D «Cosine Mandelbulb» Julia-mengde.\n"
+"17 = 4D «Mandelbulb» Mandelbrot-mengde.\n"
+"18 = 4D «Mandelbulb» Julia-mengde."
 
 #: src/settings_translation_file.cpp
 msgid "Server / Singleplayer"
@@ -5973,26 +6097,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6096,7 +6212,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr "Fet skrifttype som forvalg"
 
 #: src/settings_translation_file.cpp
@@ -6207,6 +6323,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid ""
@@ -6322,7 +6446,7 @@ msgstr "Filsti for teksturer"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6340,7 +6464,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6414,7 +6538,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6508,6 +6632,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr "Strandlydsterskel"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6582,7 +6710,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6608,7 +6736,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "VSync"
-msgstr ""
+msgstr "VSync"
 
 #: src/settings_translation_file.cpp
 msgid "Valley depth"
@@ -6771,6 +6899,11 @@ msgstr "Bølgende vann"
 msgid "Waving plants"
 msgstr "Plantesvaiing"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Farge på utvalgsfelt"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6792,7 +6925,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6800,14 +6933,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6937,24 +7063,6 @@ msgstr "Y-nivå for nedre terreng og sjøbunn."
 msgid "Y-level of seabed."
 msgstr "Y-nivå for havbunn."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Tidsutløp for filnedlasting med cURL"
@@ -6968,6 +7076,12 @@ msgstr "cURL-tidsgrense"
 msgid "cURL parallel limit"
 msgstr "Maksimal parallellisering i cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kreativ modus: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Skade: "
+
 #~ msgid "Address / Port"
 #~ msgstr "Adresse / port"
 
@@ -7032,12 +7146,18 @@ msgstr "Maksimal parallellisering i cURL"
 #~ msgid "Fallback font size"
 #~ msgstr "Tilbakefallsskriftstørrelse"
 
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType-skrifttyper"
+
 #~ msgid "Generate Normal Maps"
 #~ msgstr "Generer normale kart"
 
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6-støtte."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Installasjon: fil \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "Hovedmeny"
 
@@ -7081,6 +7201,9 @@ msgstr "Maksimal parallellisering i cURL"
 #~ msgid "Start Singleplayer"
 #~ msgstr "Start enkeltspiller"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "OpenGL-driveren må brukes for å aktivere skyggelegging."
+
 #~ msgid "View"
 #~ msgstr "Vis"
 
@@ -7093,5 +7216,8 @@ msgstr "Maksimal parallellisering i cURL"
 #~ msgid "Yes"
 #~ msgstr "Ja"
 
+#~ msgid "You died."
+#~ msgstr "Du døde."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 37ffdcc2423b48b09a0048c0657c1c97979edf5b..44c6277ed01c372abdd220eac1958621e7901e73 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Dutch (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-02-01 05:52+0000\n"
-"Last-Translator: eol <joshua.de.clercq@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-12-29 20:51+0000\n"
+"Last-Translator: Gert-dev <qnyasgjhapqyuhoibr@kiabws.com>\n"
 "Language-Team: Dutch <https://hosted.weblate.org/projects/minetest/minetest/"
 "nl/>\n"
 "Language: nl\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5-dev\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Maximale omvang van de wachtrij uitgezonden berichten"
+msgstr "Wachtrij voor uitgezonden berichten legen"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Chat-commando's"
+msgstr "Instructie voor legen."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Terug naar menu"
+msgstr "Terug naar hoofd menu"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Lokale commando"
+msgstr "Ongeldige instructie "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Opgegeven instructie: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Singleplayer"
+msgstr "Online spelers weergeven"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Singleplayer"
+msgstr "Online spelers: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "De wachtrij voor uitgezonden berichten is nu leeg."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Deze instructie is uitgeschakeld door de server."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,41 @@ msgstr "Herboren worden"
 msgid "You died"
 msgstr "Je bent gestorven"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Je bent gestorven"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Lokale commando"
+msgstr "Beschikbare instructies:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Lokale commando"
+msgstr "Beschikbare instructies: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Instructie niet beschikbaar: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Krijg hulp voor instructies"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Gebruik '.help <cmd>' om meer informatie te verkrijgen, of '.help all' om "
+"alles weer te geven."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <commando>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "Oke"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<geen beschikbaar>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Er is een fout opgetreden in een Lua script:"
@@ -304,6 +297,10 @@ msgstr "Installeer $1"
 msgid "Install missing dependencies"
 msgstr "Installeer ontbrekende afhankelijkheden"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Installeren: Niet ondersteund bestandstype of defect archief"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -636,7 +633,7 @@ msgid "Offset"
 msgstr "afstand"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Persistentie"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -747,14 +744,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Mod installeren: kan geen geschikte map naam vinden voor mod verzameling $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Installeren: niet ondersteund bestandstype \"$1\" of defect archief"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Installeer: bestand: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Niet mogelijk om geschikte map-naam vinden voor modverzameling $1"
@@ -780,9 +769,8 @@ msgid "Loading..."
 msgstr "Laden..."
 
 #: builtin/mainmenu/serverlistmgr.lua
-#, fuzzy
 msgid "Public server list is disabled"
-msgstr "Client-side scripting is uitgeschakeld"
+msgstr "Publieke serverlijst is uitgeschakeld"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
@@ -792,16 +780,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Over"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Andere actieve ontwikkelaars"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Bereik waarbinnen actieve objecten gestuurd worden"
+msgstr "Actieve renderer:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -936,9 +923,8 @@ msgid "Start Game"
 msgstr "Start spel"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adres: "
+msgstr "Adres"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -954,22 +940,20 @@ msgstr "Creatieve modus"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Verwondingen/schade"
+msgstr "Schade / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Verwijder Favoriete"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "Favorieten"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Incompatibele Servers"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -980,18 +964,16 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Server aanmelden bij de server-lijst"
+msgstr "Publieke Servers"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Verversen"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Omschrijving van de server"
+msgstr "Omschrijving van de Server"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1023,7 +1005,7 @@ msgstr "Schermafmetingen automatisch bewaren"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Bilinear Filter"
-msgstr "Bilineaire Filtering"
+msgstr "Bilineair filteren"
 
 #: builtin/mainmenu/tab_settings.lua src/client/game.cpp
 msgid "Change Keys"
@@ -1034,13 +1016,12 @@ msgid "Connected Glass"
 msgstr "Verbonden Glas"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Fontschaduw"
+msgstr "Dynamische schaduwen"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dynamische schaduwen: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1048,15 +1029,15 @@ msgstr "Mooie bladeren"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Hoog"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Laag"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Gemiddeld"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1130,10 +1111,6 @@ msgstr "Vloeiende verlichting"
 msgid "Texturing:"
 msgstr "Textuur:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Om schaduwen mogelijk te maken moet OpenGL worden gebruikt."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tone-mapping"
@@ -1144,15 +1121,15 @@ msgstr "Toetsgrenswaarde: (px)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Trilinear Filter"
-msgstr "Tri-Lineare Filtering"
+msgstr "Trilineair filteren"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Zeer Hoog"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Zeer Laag"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1166,7 +1143,7 @@ msgstr "Golvende Vloeistoffen"
 msgid "Waving Plants"
 msgstr "Bewegende planten"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Time-out bij opzetten verbinding."
 
@@ -1195,8 +1172,8 @@ msgid "Connection error (timed out?)"
 msgstr "Fout bij verbinden (time out?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Kan het spel niet laden of niet vinden \""
+msgid "Could not find or load game"
+msgstr "Kan het spel niet vinden of laden: "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1238,14 +1215,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adres: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Creatieve Modus: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Verwondingen: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Mode(creatief/overleving): "
@@ -1267,6 +1236,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Server Naam: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Er is een serialisatie-fout opgetreden:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Toegang geweigerd. Reden: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automatisch vooruit uitgeschakeld"
@@ -1275,6 +1253,22 @@ msgstr "Automatisch vooruit uitgeschakeld"
 msgid "Automatic forward enabled"
 msgstr "Automatisch vooruit ingeschakeld"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Blokgrenzen verborgen"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Blokgrenzen getoond voor alle blokken"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Blokgrenzen getoond voor huidige blok"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Blokgrenzen getoond voor nabije blokken"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Camera-update uitgeschakeld"
@@ -1283,6 +1277,10 @@ msgstr "Camera-update uitgeschakeld"
 msgid "Camera update enabled"
 msgstr "Camera-update ingeschakeld"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Kan blokgrenzen niet tonen (privilege 'basic_debug' is nodig)"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Verander wachtwoord"
@@ -1295,6 +1293,10 @@ msgstr "Filmische modus uitgeschakeld"
 msgid "Cinematic mode enabled"
 msgstr "Filmische modus ingeschakeld"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Gebruiker heeft verbinding verbroken"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Client-side scripting is uitgeschakeld"
@@ -1303,6 +1305,10 @@ msgstr "Client-side scripting is uitgeschakeld"
 msgid "Connecting to server..."
 msgstr "Verbinding met de server wordt gemaakt..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Verbinding mislukt om onbekende reden"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Verder spelen"
@@ -1340,6 +1346,11 @@ msgstr ""
 "- Muiswiel: item selecteren \n"
 "-%s: chat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Adres kon niet opgezocht worden: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Gebruiker aanmaken..."
@@ -1469,9 +1480,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Mini-kaart momenteel uitgeschakeld door spel of mod"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Singleplayer"
+msgstr "Multiplayer"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1545,6 +1555,21 @@ msgstr "Geluidssysteem is niet ondersteund in deze versie"
 msgid "Sound unmuted"
 msgstr "Geluid niet gedempt"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "De server gebruikt waarschijnlijk een andere versie van %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Kon niet verbinden met %s omdat IPv6 uitgeschakeld werd"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Kon niet luisteren naar %s omdat IPv6 uitgeschakeld werd"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1879,6 +1904,14 @@ msgstr "Minimap in oppervlaktemodus, Zoom x%d"
 msgid "Minimap in texture mode"
 msgstr "Minimap textuur modus"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Openen van webpagina mislukt"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Website openen"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "De wachtwoorden zijn niet gelijk!"
@@ -1909,9 +1942,8 @@ msgid "Proceed"
 msgstr "Doorgaan"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Speciaal\" = naar beneden klimmen"
+msgstr "\"Aux1\" = naar beneden klimmen"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1923,7 +1955,7 @@ msgstr "Automatisch springen"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1931,7 +1963,7 @@ msgstr "Achteruit"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Blok grenzen"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2084,8 +2116,9 @@ msgid "Muted"
 msgstr "Gedempt"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Geluidsvolume: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Geluidsvolume: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2110,14 +2143,13 @@ msgstr ""
 "van de eerste aanraking."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Gebruik virtuele joystick om de \"aux\" -knop te activeren. \n"
-"Indien ingeschakeld, zal de virtuele joystick ook op de \"aux\" -knop tikken "
+"(Android) Gebruik virtuele joystick om de \"aux\"-knop te activeren.\n"
+"Indien ingeschakeld, zal de virtuele joystick ook op de \"aux\"-knop tikken "
 "wanneer deze buiten de hoofdcirkel is."
 
 #: src/settings_translation_file.cpp
@@ -2346,6 +2378,12 @@ msgstr ""
 "Pas de dpi-configuratie aan op uw scherm (alleen niet X11 / Android), b.v. "
 "voor 4k-schermen."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Pas de gedetecteerde weergavedichtheid aan, gebruikt om elementen uit de "
+"gebruikersinterface te schalen."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2399,7 +2437,7 @@ msgstr "Versterkt de valleien."
 
 #: src/settings_translation_file.cpp
 msgid "Anisotropic filtering"
-msgstr "Anisotropische filtering"
+msgstr "Anisotropisch filteren"
 
 #: src/settings_translation_file.cpp
 msgid "Announce server"
@@ -2485,14 +2523,12 @@ msgid "Autoscaling mode"
 msgstr "Automatische schaalmodus"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Springen toets"
+msgstr "Aux1-toets"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Gebruik de 'speciaal'-toets voor klimmen en dalen"
+msgstr "Aux1-toets voor klimmen/afdalen"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2524,7 +2560,7 @@ msgstr "Strand geluid grenswaarde"
 
 #: src/settings_translation_file.cpp
 msgid "Bilinear filtering"
-msgstr "Bi-Lineaire filtering"
+msgstr "Bilineair filteren"
 
 #: src/settings_translation_file.cpp
 msgid "Bind address"
@@ -2644,9 +2680,12 @@ msgstr ""
 "Waar 0,0 het minimale lichtniveau is, is 1,0 het maximale lichtniveau."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Drempel voor kick van chatbericht"
+msgstr "Tijdsdrempel voor berichten chatcommando's"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Chatcommando's"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2681,8 +2720,8 @@ msgid "Chat toggle key"
 msgstr "Toets voor tonen/verbergen chat"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Chat-commando's"
+msgid "Chat weblinks"
+msgstr "Weblinks chat"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2700,6 +2739,14 @@ msgstr "Cinematic modus aan/uit toets"
 msgid "Clean transparent textures"
 msgstr "Schone transparante texturen"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Aanklikbare weblinks (middelklik of ctrl+linkermuisklik) ingeschakedl in "
+"console-uitvoer chat."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Cliënt"
@@ -2745,9 +2792,8 @@ msgid "Colored fog"
 msgstr "Gekleurde mist"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Gekleurde mist"
+msgstr "Gekleurde schaduwen"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2791,6 +2837,30 @@ msgstr ""
 msgid "Command key"
 msgstr "Commando-toets"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Compressieniveau bij bewaren mapblokken op harde schijf.\n"
+"-1 - standaardcompressieniveau\n"
+"0 - minste compressie, snelst\n"
+"9 - meeste compressie, traagst"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Compressieniveau bij versturen mapblokken naar cliënt.\n"
+"-1 - standaardcompressieniveau\n"
+"0 - minste compressie, snelst\n"
+"9 - meeste compressie, traagst"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Verbind glas"
@@ -2895,10 +2965,10 @@ msgstr "Draadkruis-alphawaarde"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
-"Draadkruis-alphawaarde (ondoorzichtigheid; tussen 0 en 255).\n"
-"Controleert ook het object draadkruis kleur"
+"Alfawaarde crosshair (ondoorzichtigheid, tussen 0 en 255).\n"
+"Ook van toepassing op de crosshair voor objecten."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2978,10 +3048,13 @@ msgstr "Standaard voorwerpenstapel grootte"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Definieer kwaliteit schaduwfiltering\n"
+"Dit simuleert zachte schaduwen d.m.v. een PCF of Poisson-schijf\n"
+"maar is ook gebruiksintensiever."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3107,6 +3180,10 @@ msgstr "Valsspeelbescherming uitschakelen"
 msgid "Disallow empty passwords"
 msgstr "Lege wachtwoorden niet toestaan"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Weergavedichtheid-schaalfactor"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Domeinnaam van de server; wordt getoond in de serverlijst."
@@ -3137,7 +3214,7 @@ msgstr "Dungeon minimaal Y"
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon noise"
-msgstr "Kerker ruis"
+msgstr "Lawaai in kerkers"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3157,18 +3234,30 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Filteren d.m.v. Poisson-schijf inschakelen.\n"
+"Indien ingeschakeld, wordt een Poisson-schijf gebruikt om zachte schaduwen "
+"te genereren. In het andere geval wordt PCF-filteren toegepast."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Gekleurde schaduwen inschakelen.\n"
+"Indien ingeschakeld werpen doorzichtige nodes gekleurde schaduwen af. Dit is "
+"arbeidsintensief."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
 msgstr "Schakel het console venster in"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable creative mode for all players"
-msgstr "Schakel creatieve modus in voor nieuwe kaarten."
+msgstr "Schakel creatieve modus in voor alle spelers"
 
 #: src/settings_translation_file.cpp
 msgid "Enable joysticks"
@@ -3186,13 +3275,6 @@ msgstr "Veilige modus voor mods aanzetten"
 msgid "Enable players getting damage and dying."
 msgstr "Schakel verwondingen en sterven van spelers aan."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Schakel willkeurige invoer aan (enkel voor testen)."
@@ -3309,6 +3391,12 @@ msgstr ""
 "volledig uitgeschakeld geluidsbesturingen zullen niet functioneel zijn. \n"
 "Het wijzigen van deze instelling vereist een herstart."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Profilergegevens print interval"
@@ -3371,13 +3459,12 @@ msgid "Fast movement"
 msgstr "Snelle modus"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Snelle beweging (via de \"speciaal\" toets). \n"
-"Dit vereist het \"snel bewegen\" recht op de server."
+"Snelle beweging (via de \"Aux1\"-toets).\n"
+"Dit vereist het recht \"snel bewegen\" op de server."
 
 #: src/settings_translation_file.cpp
 msgid "Field of view"
@@ -3410,18 +3497,18 @@ msgid "Filmic tone mapping"
 msgstr "Filmisch tone-mapping"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
 "light edges to transparent textures. Apply a filter to clean that up\n"
 "at texture load time. This is automatically enabled if mipmapping is enabled."
 msgstr ""
-"Gefilterde texturen kunnen RGB-waarden vermengen met transparante buren,\n"
-"die door PNG-optimalisators vaak verwijderd worden. Dit kan donkere of "
-"lichte\n"
-"randen bij transparante texturen tot gevolg hebben.\n"
-"Gebruik dit filter om dat tijdens het laden van texturen te herstellen."
+"Gefilterde texturen kunnen RGB-waarden mengen met die van volledig\n"
+"transparante buren, die door PNG-optimalisatoren vaak verwijderd worden,\n"
+"wat vaak voor donkere of lichtere randen bij transparante texturen zorgt.\n"
+"Gebruik een filter om dat tijdens het laden van texturen te herstellen. Dit "
+"wordt\n"
+"automatisch ingeschakeld als mipmapping aan staat."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3514,11 +3601,17 @@ msgid "Font size"
 msgstr "Lettergrootte"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Lettergrootte van het standaardlettertype in punt (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Lettergrootte van het monospace-lettertype in punt (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3529,6 +3622,17 @@ msgstr ""
 "Tekstgrootte van de chatgeschiedenis en chat prompt in punten (pt).\n"
 "Waarde 0 zal de standaard tekstgrootte gebruiken."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3594,10 +3698,6 @@ msgstr "Fractaal type"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Fractie van de zichtbare afstand vanaf waar de nevel wordt getoond"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Freetype lettertypes"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3657,16 +3757,13 @@ msgstr "Algemene callbacks"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
-"Algemene wereldgenerator instellingen.\n"
-"De vlag 'decorations' bepaalt de aanwezigheid van alle decoraties, behalve\n"
-"bij generator v6,\n"
-"waar de aanwezigheid van bomen en oerwoud-gras er niet\n"
-"door beïnvloed wordt.\n"
-"Vlaggen die niet in de lijst van vlaggen staan, behouden hun standaard-"
-"waarde.\n"
-"Zet \"no\" voor een vlag om hem expliciet uit te zetten."
+"Algemene wereldgeneratorinstellingen.\n"
+"In Mapgen v6 beïnvloedt de vlag \"decorations\" alle decoraties behalve "
+"bomen.\n"
+"en junglegras. In alle andere generatoren beïnvloedt deze vlag alle "
+"decoraties."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3749,10 +3846,11 @@ msgid "Heat noise"
 msgstr "Hitte geluid"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Aanvangshoogte van het venster."
+msgstr ""
+"Hoogtecomponent van de initiële grootte van het venster. Wordt genegeerd in "
+"fullscreen-modus."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -4006,14 +4104,12 @@ msgstr ""
 "kracht verspild wordt zonder dat het toegevoegde waarde heeft."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Indien uitgeschakeld, dan wordt met de \"speciaal\" toets snel gevlogen "
-"wanneer\n"
-"de \"vliegen\" en de \"snel\" modus aanstaan."
+"Indien uitgeschakeld wordt de \"Aux1\"-toets gebruikt om snel te vliegen\n"
+"als modi \"vliegen\" en \"snel\" beide aan staan."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4041,14 +4137,14 @@ msgstr ""
 "Dit vereist het \"noclip\" voorrecht op de server."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Indien aangeschakeld, dan wordt de \"speciaal\" toets gebruikt voor\n"
-"omlaagklimmen en dalen i.p.v. de \"sluipen\" toets."
+"Indien ingeschakeld wordt de \"Aux1\"-toets gebruikt i.p.v. de \"Sneak\"-"
+"toets om\n"
+"omlaag te klimmen en af te dalen."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4110,6 +4206,8 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Als het uitvoeren van een chatcommando langer duurt dan de opgegeven tijd\n"
+"in seconden, voeg dan tijdsinformatie toe aan het bijhorende bericht"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4170,8 +4268,8 @@ msgstr ""
 "het core/builtin-gedeelte van de server"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
-msgstr "Profileer chat-commando's bij het registreren."
+msgid "Instrument chat commands on registration."
+msgstr "Profileer chatcommando's bij het registreren."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4264,8 +4362,8 @@ msgid "Joystick button repetition interval"
 msgstr "Joystick-knop herhalingsinterval"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
-msgstr "Joystick dode zone"
+msgid "Joystick dead zone"
+msgstr "Dode zone Joystick"
 
 #: src/settings_translation_file.cpp
 msgid "Joystick frustum sensitivity"
@@ -5382,9 +5480,8 @@ msgid "Map save interval"
 msgstr "Interval voor opslaan wereld"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Vloeistof verspreidingssnelheid"
+msgid "Map shadows update frames"
+msgstr "Aantal frames voor bijwerken schaduwmap"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5500,7 +5597,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Maximumafstand bij renderen schaduwen."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5635,12 +5732,11 @@ msgstr ""
 "'0' om de wachtrij uit te schakelen en '-1' om de wachtrij oneindig te maken."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Maximale duur voor een download van een bestand (bijv. een mod). In "
+"Maximale duur voor het downloaden van een bestand (bv. een mod), in "
 "milliseconden."
 
 #: src/settings_translation_file.cpp
@@ -5648,6 +5744,8 @@ msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Maximale duur voor het afhandelen van een interactieve aanvraag (bv. ophalen "
+"serverlijst), in milliseconden."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5713,8 +5811,8 @@ msgid "Mod channels"
 msgstr "Mod-kanalen"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "Veranderd de grootte van de HUDbar elementen."
+msgid "Modifies the size of the HUD elements."
+msgstr "Verandert de grootte van de HUD-elementen."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
@@ -5724,6 +5822,11 @@ msgstr "Vaste-breedte font pad"
 msgid "Monospace font size"
 msgstr "Vaste-breedte font grootte"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Vaste-breedte font grootte"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Berg-hoogte ruis"
@@ -5880,15 +5983,12 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
-"Aantal extra blokken (van 16x16x16 nodes) dat door het commando '/"
-"clearobjects'\n"
-"tegelijk geladen mag worden.\n"
-"Dit aantal is een compromis tussen snelheid enerzijds (vanwege de overhead "
-"van een sqlite\n"
-"transactie), en geheugengebruik anderzijds (4096 = ca. 100MB)."
+"Aantal extra blokken dat '/clearobjects' tegelijk mag laden.\n"
+"Dit is een compromis tussen overhead van SQLite-transacties en\n"
+"geheugengebruik (als vuistregel is 4096 gelijk aan 100 MB)."
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
@@ -5915,10 +6015,13 @@ msgstr ""
 "een formspec geopend is."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Optionele overschrijving van de kleur van weblinks in chat."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5953,10 +6056,9 @@ msgstr ""
 "Pad van de texturen-map. Naar texturen wordt gezocht beginnend bij deze map."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Pad naar het standaardlettertype. \n"
@@ -5968,10 +6070,9 @@ msgstr ""
 "geladen."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Pad naar het monospace-lettertype. \n"
@@ -6035,9 +6136,8 @@ msgid "Player versus player"
 msgstr "Speler tegen speler"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Bi-Lineaire filtering"
+msgstr "Poisson-filteren"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6092,14 +6192,14 @@ msgstr "Adres om te luisteren naar Prometheus"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Adres om te luisteren naar Prometheus.\n"
-"Als Minetest is gecompileerd met de optie ENABLE_PROMETHEUS,\n"
-"zal dit adres gebruikt worden om naar Prometheus te luisteren.\n"
-"Meetwaarden zullen kunnen bekeken worden op http://127.0.0.1:30000/metrics"
+"Indien Minetest gecompileerd werd met de optie ENABLE_PROMETHEUS,\n"
+"dan zal dit adres gebruikt worden om naar Prometheus te luisteren.\n"
+"Meetwaarden kunnen opgehaald worden op http://127.0.0.1:30000/metrics"
 
 #: src/settings_translation_file.cpp
 msgid "Proportion of large caves that contain liquid."
@@ -6437,37 +6537,37 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Schaduwsterkte instellen.\n"
+"Een lagere waarde betekent lichtere schaduwen, een hogere waarde donkerdere "
+"schaduwen."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Radiusgrootte zachte schaduwen instellen.\n"
+"Lagere waarden betekenen scherpere schaduwen, hogere waarden zachtere.\n"
+"Minimumwaarde: 1.0; maximumwaarde: 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Tilt van baan zon/maan in graden instellen:\n"
+"Een waarde van 0 betekent geen tilt / verticale baan.\n"
+"Minimumwaarde: 0.0; maximumwaarde: 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Bewegende bladeren staan aan indien 'true'.\n"
-"Dit vereist dat 'shaders' ook aanstaan."
+"Schakel in om schaduwmapping in te schakelen.\n"
+"Dit vereist dat 'shaders' ook aan staan."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6499,6 +6599,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Schaduwtextuurkwaliteit op 32-bits zetten.\n"
+"Indien uitgeschakeld worden 16-bits texturen gebruikt,\n"
+"wat voor meer ruis in schaduwen kan zorgen."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6516,22 +6619,20 @@ msgstr ""
 "Alleen mogelijk met OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Screenshot kwaliteit"
+msgstr "Kwaliteit schaduwfilter"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Maximumafstand in nodes om schaduwen schaduwmap op te renderen"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "32-bits-schaduwmaptexturen"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Minimale textuur-grootte"
+msgstr "Textuurgrootte schaduwmap"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6543,7 +6644,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Schaduwsterkte"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6566,9 +6667,8 @@ msgstr ""
 "Een herstart is noodzakelijk om de wijziging te activeren."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Show nametag backgrounds by default"
-msgstr "Standaard vetgedrukt"
+msgid "Show name tag backgrounds by default"
+msgstr "Standaard achtergronden naam-tags tonen"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6604,7 +6704,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Tilt baan hemellichaam"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6665,9 +6765,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Sluipsnelheid, in blokken per seconde."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Fontschaduw alphawaarde"
+msgstr "Radius zachte schaduwen"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6696,6 +6795,19 @@ msgstr ""
 "Merk op dat mods of spellen expliciet een stack kunnen maken voor sommige "
 "(of alle) items."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Verspeid een volledige update van de schaduwmap over het opgegeven aantal "
+"frames.\n"
+"Hogere waarden kunnen schaduwen \"laggy\" maken, lagere\n"
+"waarden kosten meer moeite.\n"
+"Minimumwaarde: 1; maximumwaarde: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6834,8 +6946,11 @@ msgstr "Textuur pad"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Grootte textuur om de schaduwmap op te renderen.\n"
+"Dit moet een macht van twee zijn.\n"
+"Grotere numbers zorgen voor betere schaduwen maar kosten ook meer moeite."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6862,8 +6977,8 @@ msgid "The URL for the content repository"
 msgstr "De URL voor de inhoudsrepository"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
-msgstr "De dode zone van de stuurknuppel die u gebruikt"
+msgid "The dead zone of the joystick"
+msgstr "De dode zone van de joystick"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6939,7 +7054,6 @@ msgstr ""
 "Dit moet samen met active_object_send_range_blocks worden geconfigureerd."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6948,21 +7062,21 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"De rendering back-end voor Irrlicht. \n"
-"Na het wijzigen hiervan is een herstart vereist. \n"
-"Opmerking: op Android, blijf bij OGLES1 als je het niet zeker weet! Anders "
-"start de app mogelijk niet. \n"
+"Back-end om mee te renderen.\n"
+"Een herstart is vereist om dit definitief te wijzigen.\n"
+"Opmerking: Op Android, blijf bij OGLES1 als je het niet zeker weet! Anders "
+"start de app mogelijk niet.\n"
 "Op andere platformen wordt OpenGL aanbevolen.\n"
-"OpenGL (alleen op desktop pc) en OGLES2 (experimenteel), zijn de enige "
-"drivers met shader-ondersteuning momenteel"
+"Zowel OpenGL (alleen op desktop) als OGLES2 (experimenteel) ondersteunen "
+"shaders"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
-"De gevoeligheid van de assen van de joystick voor het bewegen van de "
-"frustrum in het spel."
+"De gevoeligheid van de assen van de joystick bij\n"
+"het bewegen van de camera-frustum in het spel."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7085,13 +7199,17 @@ msgstr "Tooltip tijdsduur"
 msgid "Touch screen threshold"
 msgstr "Gevoeligheid van het aanraakscherm"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Bomen ruis"
 
 #: src/settings_translation_file.cpp
 msgid "Trilinear filtering"
-msgstr "Tri-Lineare Filtering"
+msgstr "Trilineair filteren"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7156,21 +7274,20 @@ msgstr "Toon wolken in de achtergrond van het hoofdmenu."
 
 #: src/settings_translation_file.cpp
 msgid "Use anisotropic filtering when viewing at textures from an angle."
-msgstr "Gebruik anisotropische filtering voor texturen getoond onder een hoek."
+msgstr "Gebruik anisotropisch filteren voor texturen getoond onder een hoek."
 
 #: src/settings_translation_file.cpp
 msgid "Use bilinear filtering when scaling textures."
-msgstr "Gebruik bi-lineaire filtering bij het schalen van texturen."
+msgstr "Gebruik bilineair filteren bij het schalen van texturen."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
-"Gebruik mip-mapping om texturen te schalen. Kan de prestaties enigszins "
-"verbeteren, \n"
-"vooral bij gebruik van een textuurpakket met hoge resolutie. \n"
+"Mipmapping gebruiken om texturen te schalen. Kan performantie lichtjes\n"
+"verbeteren, vooral in combinatie met textuurpakketten van hoge resolutie.\n"
 "Gamma-correcte verkleining wordt niet ondersteund."
 
 #: src/settings_translation_file.cpp
@@ -7194,7 +7311,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Use trilinear filtering when scaling textures."
-msgstr "Gebruik tri-lineaire filtering om texturen te schalen."
+msgstr "Gebruik trilineair filteren om texturen te schalen."
 
 #: src/settings_translation_file.cpp
 msgid "VBO"
@@ -7293,9 +7410,8 @@ msgid "Viewing range"
 msgstr "Zichtafstand"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Virtuele joystick activeert aux-knop"
+msgstr "Virtuele joystick activeert Aux1-toets"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7371,6 +7487,10 @@ msgstr "Golflengte van water/vloeistoffen"
 msgid "Waving plants"
 msgstr "Bewegende planten"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Kleur weblinks"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7396,48 +7516,33 @@ msgstr ""
 "terug naar het werkgeheugen."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
 msgstr ""
-"Als bi-lineaire, tri-lineaire of anisotropische filters gebruikt worden, "
-"dan\n"
-"kunnen lage-resolutie texturen vaag worden. Verhoog hun resolutie dmv\n"
-"naaste-buur-interpolatie zodat de scherpte behouden blijft. Deze optie\n"
-"bepaalt de minimale textuurgroote na het verhogen van de resolutie. Hogere\n"
-"waarden geven een scherper beeld, maar kosten meer geheugen. Het is "
-"aanbevolen\n"
-"machten van 2 te gebruiken. Een waarde groter dan 1 heeft wellicht geen "
-"zichtbaar\n"
-"effect indien bi-lineaire, tri-lineaire of anisotropische filtering niet aan "
-"staan.\n"
-"Dit wordt ook gebruikt als basis node textuurgrootte voor wereld-"
-"gealigneerde\n"
-"automatische textuurschaling."
+"Bij gebruik bilineair/trilineair/anisotropisch filteren kunnen texturen van\n"
+"lage resolutie vaag worden; verhoog daardoor hun resolutie d.m.v.\n"
+"\"naaste-buur-interpolatie\" om ze scherper te houden. Deze optie bepaalt\n"
+"de minimale textuurgrootte na het omhoog schalen; hogere waarden geven\n"
+"scherper beeld, maar kosten meer geheugen. Het is aanbevolen machten van\n"
+"2 te gebruiken. Deze optie heeft enkel effect als bilineair, trilineair of\n"
+"anisotropisch filteren aan staan.\n"
+"Deze optie geldt ook als textuurgrootte van basisnodes voor\n"
+"automatisch en met de wereld gealigneerd omhoog schalen van texturen."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Gebruik freetype lettertypes, dit vereist dat freetype lettertype "
-"ondersteuning ingecompileerd is.\n"
-"Indien uitgeschakeld, zullen bitmap en XML verctor lettertypes gebruikt "
-"worden."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
+"Of achtergronden van naam-tags standaard getoond moeten worden.\n"
+"Mods kunnen alsnog een achtergrond instellen."
 
 #: src/settings_translation_file.cpp
 msgid "Whether node texture animations should be desynchronized per mapblock."
@@ -7490,9 +7595,10 @@ msgstr ""
 "toets)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Aanvangsbreedte van het venster."
+msgstr ""
+"Breedtecomponent van de initiële grootte van het venster. Wordt genegeerd in "
+"fullscreen-modus."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7600,49 +7706,24 @@ msgstr "Y-niveau van lager terrein en vijver/zee bodems."
 msgid "Y-level of seabed."
 msgstr "Y-niveau van zee bodem."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Zlib compressie niveau om mapblokken op de harde schijf te bewaren.\n"
-"-1: Zlib's standaard compressie niveau\n"
-"0: geen compressie, snelst\n"
-"9: maximale compressie, traagst\n"
-"(niveau's 1 tot 3 gebruiken Zlib's snelle methode, 4 tot 9 gebruiken de "
-"normale methode)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Zlib compressie niveau om mapblokken te versturen naar de client.\n"
-"-1: Zlib's standaard compressie niveau\n"
-"0: geen compressie, snelst\n"
-"9: maximale compressie, traagst\n"
-"(niveau's 1 tot 3 gebruiken Zlib's snelle methode, 4 tot 9 gebruiken de "
-"normale methode)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "timeout voor cURL download"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL time-out"
+msgstr "cURL interactieve time-out"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "Maximaal parallellisme in cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Creatieve Modus: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Verwondingen: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7810,6 +7891,9 @@ msgstr "Maximaal parallellisme in cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Lettergrootte van het fallback-lettertype in punt (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Freetype lettertypes"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP bij volledig scherm"
 
@@ -7829,6 +7913,9 @@ msgstr "Maximaal parallellisme in cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 ondersteuning."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Installeer: bestand: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "Diepte van grote grotten"
@@ -7956,6 +8043,9 @@ msgstr "Maximaal parallellisme in cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Dit font wordt gebruikt voor bepaalde talen."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Om schaduwen mogelijk te maken moet OpenGL worden gebruikt."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Cinematic modus aan/uit"
 
@@ -7979,6 +8069,16 @@ msgstr "Maximaal parallellisme in cURL"
 #~ msgid "Waving water"
 #~ msgstr "Golvend water"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Gebruik freetype lettertypes, dit vereist dat freetype lettertype "
+#~ "ondersteuning ingecompileerd is.\n"
+#~ "Indien uitgeschakeld, zullen bitmap en XML verctor lettertypes gebruikt "
+#~ "worden."
+
 #, fuzzy
 #~ msgid "Y of upper limit of lava in large caves."
 #~ msgstr "Minimale diepte van grote semi-willekeurige grotten."
@@ -7992,5 +8092,8 @@ msgstr "Maximaal parallellisme in cURL"
 #~ msgid "Yes"
 #~ msgstr "Ja"
 
+#~ msgid "You died."
+#~ msgstr "Je bent gestorven."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 746ac0d008f064d0d1520e9fcd4f2a0fd96cbba3..2cf2ef0cbaf07339480a916df2cc022b17c5c333 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Norwegian Nynorsk (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-02-20 05:50+0000\n"
 "Last-Translator: Tor Egil Hoftun Kvæstad <toregilhk@hotmail.com>\n"
 "Language-Team: Norwegian Nynorsk <https://hosted.weblate.org/projects/"
@@ -62,11 +62,6 @@ msgstr "Du har kome at"
 msgid "You died"
 msgstr "Du døydde"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Du døydde"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -98,6 +93,10 @@ msgstr ""
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Ein feil oppstod i eit LUA-skript:"
@@ -299,6 +298,12 @@ msgstr "Installer $1"
 msgid "Install missing dependencies"
 msgstr "Installer manglande avhengigheiter"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"Installer: Ikkje-støtta dokument type \"$1\" eller så funker ikkje arkivet"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -628,7 +633,8 @@ msgid "Offset"
 msgstr "Forskyvning"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Persistens"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -742,16 +748,6 @@ msgstr ""
 "Installer modifikasjon: Klarte ikkje å finne ein passande katalog for "
 "modifikasjonspakke $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Installer: Ikkje-støtta dokument type \"$1\" eller så funker ikkje arkivet"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Installer: fil: «$1»"
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Klarte ikkje å finne ein gyldig modifikasjon eller modifikasjonspakke"
@@ -1133,11 +1129,6 @@ msgstr "Jevn belysning"
 msgid "Texturing:"
 msgstr "Teksturering:"
 
-#: builtin/mainmenu/tab_settings.lua
-#, fuzzy
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "For å aktivere skumrings-effekt så må OpenGL driveren være i bruk."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 #, fuzzy
 msgid "Tone Mapping"
@@ -1174,7 +1165,7 @@ msgstr "Raslende lauv"
 msgid "Waving Plants"
 msgstr "Raslende planter"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Nett-kopling er brutt."
 
@@ -1204,7 +1195,8 @@ msgid "Connection error (timed out?)"
 msgstr "Tilkoplingsfeil (Tidsavbrot?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Kunne ikkje finne eller laste spelet \""
 
 #: src/client/clientlauncher.cpp
@@ -1250,15 +1242,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresse: "
 
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Creative Mode: "
-msgstr "- Gude løyving: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Skade: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- modus: "
@@ -1280,6 +1263,16 @@ msgstr "- Spelar mot spelar (PvP): "
 msgid "- Server Name: "
 msgstr "- Tenarnamn: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Det har skjedd ein feil:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automatiske framsteg er avtatt"
@@ -1288,6 +1281,22 @@ msgstr "Automatiske framsteg er avtatt"
 msgid "Automatic forward enabled"
 msgstr "Automatiske framsteg er i gang"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kamera oppdatering er deaktivert"
@@ -1296,6 +1305,10 @@ msgstr "Kamera oppdatering er deaktivert"
 msgid "Camera update enabled"
 msgstr "Kamera oppdatering er aktivert"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Byt kodeord"
@@ -1308,6 +1321,10 @@ msgstr "Filmatisk modus er avtatt"
 msgid "Cinematic mode enabled"
 msgstr "Filmatisk modus er i gang"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Klient side-skildring er av"
@@ -1316,6 +1333,10 @@ msgstr "Klient side-skildring er av"
 msgid "Connecting to server..."
 msgstr "Kopler til tenarmaskin..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Fortset"
@@ -1353,6 +1374,11 @@ msgstr ""
 "- Musehjul: vel ting\n"
 "- %s: nettprat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Skapar klient..."
@@ -1559,6 +1585,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Lyd e ikkje dempa lengre"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1894,6 +1935,15 @@ msgstr "Minikart i overflatemodus, Zoom x%d"
 msgid "Minimap in texture mode"
 msgstr "Minikart i overflate modus, Zoom x1"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Klarte ikkje å laste ned $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Passorda passar ikkje!"
@@ -2098,7 +2148,8 @@ msgid "Muted"
 msgstr "Målbindt"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Lydstyrke: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2308,6 +2359,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2574,6 +2629,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Befaling"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "Tekststørrelse for nettprat"
@@ -2607,8 +2667,9 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Skravlerøret er vist"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2626,6 +2687,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klient"
@@ -2702,6 +2769,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2793,7 +2876,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2872,8 +2955,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2991,6 +3074,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3037,7 +3124,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3065,13 +3159,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3156,6 +3243,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3340,11 +3433,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3353,6 +3450,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3412,10 +3520,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3464,7 +3568,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3896,7 +4000,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3980,7 +4084,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4809,7 +4913,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5102,7 +5206,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5113,6 +5217,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5234,7 +5342,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5258,11 +5366,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5285,17 +5395,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5398,9 +5504,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5693,26 +5799,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5803,7 +5901,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5909,6 +6007,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6019,7 +6125,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6037,7 +6143,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6106,7 +6212,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6199,6 +6305,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6269,7 +6379,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6456,6 +6566,10 @@ msgstr "Bølgete vatn"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6477,7 +6591,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6485,14 +6599,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6618,24 +6725,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6648,6 +6737,13 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#, fuzzy
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Gude løyving: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Skade: "
+
 #~ msgid "Address / Port"
 #~ msgstr "Adresse / port"
 
@@ -6678,6 +6774,9 @@ msgstr ""
 #~ msgid "Generate Normal Maps"
 #~ msgstr "Generér normale kart"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Installer: fil: «$1»"
+
 #~ msgid "Main"
 #~ msgstr "Hovud"
 
@@ -6723,11 +6822,19 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Start enkeltspelar oppleving"
 
+#, fuzzy
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "For å aktivere skumrings-effekt så må OpenGL driveren være i bruk."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Slå på/av kameramodus"
 
 #~ msgid "Yes"
 #~ msgstr "Ja"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Du døydde"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 586c83d0c0ac11dfd474fbfb8babfa4aa1ff3ff4..ecce3cb36c6e4b4d235fb1b68098f2fb938dfb83 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Polish (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-03-28 20:29+0000\n"
-"Last-Translator: ResuUman <aparat2@wp.pl>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-12 18:52+0000\n"
+"Last-Translator: Sebastian Jasiński <w3c.jas@gmail.com>\n"
 "Language-Team: Polish <https://hosted.weblate.org/projects/minetest/minetest/"
 "pl/>\n"
 "Language: pl\n"
@@ -13,49 +13,43 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
 "|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.6-dev\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Maksymalny rozmiar kolejki wiadomości czatu"
+msgstr "Wyczyść kolejkę wiadomości czatu"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Komenda"
+msgstr "Pusta komenda."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
 msgstr "Wyjście do menu"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Lokalne polecenie"
+msgstr "Błędna komenda: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Wydana komenda: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Pojedynczy gracz"
+msgstr "Lista graczy online"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Pojedynczy gracz"
+msgstr "Gracze online: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Kolejka czatu jest teraz pusta."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Ta komenda jest dezaktywowana przez serwer."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -65,42 +59,43 @@ msgstr "Wróć do gry"
 msgid "You died"
 msgstr "Umarłeś"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Umarłeś"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Lokalne polecenie"
+msgstr "Dostępne komendy:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Lokalne polecenie"
+msgstr "Dostępne komendy: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Polecenie nie jest dostępne: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Uzyskaj pomoc dotyczącą poleceń"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Użyj '.help <cmd>', aby uzyskać więcej informacji lub '.help all', aby "
+"wyświetlić wszystko."
 
 #: builtin/common/chatcommands.lua
+#, fuzzy
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Komenda nie jest dostępna: "
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Wystąpił błąd w skrypcie Lua:"
@@ -251,14 +246,12 @@ msgstr ""
 "$2 w kolejce"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "$1 downloading..."
-msgstr "Ładowanie..."
+msgstr "Pobieranie $1..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "$1 required dependencies could not be found."
-msgstr "$1 wymaga zależności, których nie można znaleźć."
+msgstr "$1 wymaga zależności, które nie zostały znalezione."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
@@ -269,9 +262,8 @@ msgid "All packages"
 msgstr "Wszystkie zasoby"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Already installed"
-msgstr "Klawisz już zdefiniowany"
+msgstr "Już zainstalowany"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Back to Main Menu"
@@ -286,9 +278,8 @@ msgid "ContentDB is not available when Minetest was compiled without cURL"
 msgstr "ContentDB nie jest dostępne gdy Minetest był zbudowany bez cURL"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Downloading..."
-msgstr "Ładowanie..."
+msgstr "Pobieranie..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Failed to download $1"
@@ -304,14 +295,18 @@ msgid "Install"
 msgstr "Instaluj"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install $1"
-msgstr "Instaluj"
+msgstr "Zainstaluj $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Install missing dependencies"
 msgstr "Zainstaluj brakujące zależności"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Instalacja moda: nieznany typ pliku \"$1\" lub uszkodzone archiwum"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -326,14 +321,12 @@ msgid "No results"
 msgstr "Brak Wyników"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "No updates"
-msgstr "Aktualizacja"
+msgstr "Brak aktualizacji"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Not found"
-msgstr "Wycisz dźwięk"
+msgstr "Nie znaleziono"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
@@ -376,7 +369,6 @@ msgid "Additional terrain"
 msgstr "Dodatkowy teren"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Altitude chill"
 msgstr "Wysokość mrozu"
 
@@ -385,24 +377,20 @@ msgid "Altitude dry"
 msgstr "Wysokość suchości"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biome blending"
-msgstr "Szum biomu"
+msgstr "Mieszanie biomów"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biomes"
-msgstr "Szum biomu"
+msgstr "Biomy"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caverns"
-msgstr "Szum jaskini #1"
+msgstr "jaskinie"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caves"
-msgstr "Oktawy"
+msgstr "Jaskinie"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Create"
@@ -429,9 +417,8 @@ msgid "Flat terrain"
 msgstr "Płaski teren"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Floating landmasses in the sky"
-msgstr "Gęstość gór na latających wyspach"
+msgstr "Masywy lądowe unoszące się na niebie"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floatlands (experimental)"
@@ -450,9 +437,8 @@ msgid "Hills"
 msgstr "Wzgórza"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Humid rivers"
-msgstr "Sterownik graficzny"
+msgstr "Wilgotne rzeki"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Increases humidity around rivers"
@@ -477,17 +463,17 @@ msgid "Mapgen flags"
 msgstr "Flagi generatora mapy"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Mapgen-specific flags"
-msgstr "Generator mapy flat flagi"
+msgstr "Flagi specyficzne dla Mapgena"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mountains"
 msgstr "Góry"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Mud flow"
-msgstr ""
+msgstr "Strumień błota"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Network of tunnels and caves"
@@ -506,13 +492,12 @@ msgid "Reduces humidity with altitude"
 msgstr "Spadek wilgotności wraz ze wzrostem wysokości"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Rivers"
-msgstr "Rozmiar rzeki"
+msgstr "Rzeki"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Sea level rivers"
-msgstr ""
+msgstr "Rzeki na poziomie morza"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -532,44 +517,49 @@ msgstr ""
 "dżungli stworzone przez v6)"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Structures appearing on the terrain, typically trees and plants"
-msgstr ""
+msgstr "Struktury pojawiające się na terenie, zazwyczaj drzewa i rośliny"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Temperate, Desert"
-msgstr ""
+msgstr "Biocenozy klimatu umiarkowanego, pustynie"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Temperate, Desert, Jungle"
-msgstr ""
+msgstr "Biocenozy klimatu umiarkowanego, pustynie i dżungle"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr ""
+msgstr "Biocenozy klimatu umiarkowanego, pustynie, dżungla, tajga i tundra"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #, fuzzy
 msgid "Terrain surface erosion"
-msgstr "Szum podłoża"
+msgstr "Erozja powierzchni terenu"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Trees and jungle grass"
-msgstr ""
+msgstr "Drzewa i trawa w dżungli"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #, fuzzy
 msgid "Vary river depth"
-msgstr "Głębokość rzeki"
+msgstr "Zmienna głębokość rzeki"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Very large caverns deep in the underground"
-msgstr ""
+msgstr "Ogromne jaskinie na dużych głębokościach"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #, fuzzy
 msgid "Warning: The Development Test is meant for developers."
-msgstr ""
-"Uwaga: Minimal development test jest przeznaczony tylko dla developerów."
+msgstr "Ostrzeżenie: test rozwojowy jest przeznaczony dla programistów."
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "World name"
@@ -658,7 +648,8 @@ msgid "Offset"
 msgstr "Margines"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Trwałość"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -769,14 +760,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Instalacja moda: nie można znaleźć odpowiedniego folderu dla paczki modów $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Instalacja moda: nieznany typ pliku \"$1\" lub uszkodzone archiwum"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Zainstaluj mod: plik: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Nie można znaleźć prawidłowego moda lub paczki modów"
@@ -804,7 +787,7 @@ msgstr "Ładowanie..."
 #: builtin/mainmenu/serverlistmgr.lua
 #, fuzzy
 msgid "Public server list is disabled"
-msgstr "Skryptowanie po stronie klienta jest wyłączone"
+msgstr "Lista serwerów publicznych jest wyłączona"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
@@ -813,8 +796,9 @@ msgstr ""
 "z siecią Internet."
 
 #: builtin/mainmenu/tab_about.lua
+#, fuzzy
 msgid "About"
-msgstr ""
+msgstr "O grze"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
@@ -823,7 +807,7 @@ msgstr "Aktywni współautorzy"
 #: builtin/mainmenu/tab_about.lua
 #, fuzzy
 msgid "Active renderer:"
-msgstr "Zasięg wysyłania aktywnego obiektu"
+msgstr "Aktywny moduł renderowania:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -832,13 +816,17 @@ msgstr "Twórcy"
 #: builtin/mainmenu/tab_about.lua
 #, fuzzy
 msgid "Open User Data Directory"
-msgstr "Wybierz katalog"
+msgstr "Otwórz katalog danych użytkownika"
 
 #: builtin/mainmenu/tab_about.lua
+#, fuzzy
 msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"Otwiera katalog, który zawiera światy, gry, mody i tekstury dostarczone "
+"przez użytkownika\n"
+"oraz pakiety tekstur w menedżerze plików / eksploratorze."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
@@ -913,12 +901,14 @@ msgid "Host Server"
 msgstr "Udostępnij serwer"
 
 #: builtin/mainmenu/tab_local.lua
+#, fuzzy
 msgid "Install games from ContentDB"
-msgstr ""
+msgstr "Instaluj gry z ContentDB"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
+#, fuzzy
 msgid "Name"
-msgstr ""
+msgstr "Nazwa"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
@@ -931,7 +921,7 @@ msgstr "Nie wybrano bądź nie utworzono świata!"
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 #, fuzzy
 msgid "Password"
-msgstr "Nowe hasło"
+msgstr "Hasło"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
@@ -958,9 +948,8 @@ msgid "Start Game"
 msgstr "Rozpocznij grę"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "Adres "
+msgstr "Adres"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -978,7 +967,7 @@ msgstr "Tryb kreatywny"
 #: builtin/mainmenu/tab_online.lua
 #, fuzzy
 msgid "Damage / PvP"
-msgstr "Włącz obrażenia"
+msgstr "Włącz obrażenia/ PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
@@ -990,8 +979,9 @@ msgid "Favorites"
 msgstr "Ulubione"
 
 #: builtin/mainmenu/tab_online.lua
+#, fuzzy
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Niekompatybilne serwery"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -1004,14 +994,14 @@ msgstr "Ping"
 #: builtin/mainmenu/tab_online.lua
 #, fuzzy
 msgid "Public Servers"
-msgstr "Rozgłoś serwer"
+msgstr "Publiczne serwery"
 
 #: builtin/mainmenu/tab_online.lua
+#, fuzzy
 msgid "Refresh"
-msgstr ""
+msgstr "Odśwież"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Opis serwera"
 
@@ -1058,27 +1048,31 @@ msgstr "Szkło połączone"
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 #, fuzzy
 msgid "Dynamic shadows"
-msgstr "Cień czcionki"
+msgstr "Cienie dynamiczne"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Cienie dynamiczne: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
 msgstr "Ozdobne liście"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "High"
-msgstr ""
+msgstr "Wysokie"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Low"
-msgstr ""
+msgstr "Niskie"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Medium"
-msgstr ""
+msgstr "Średnie"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1135,7 +1129,7 @@ msgstr "Shadery"
 #: builtin/mainmenu/tab_settings.lua
 #, fuzzy
 msgid "Shaders (experimental)"
-msgstr "Latające wyspy (eksperymentalne)"
+msgstr "Shadery (eksperymentalne)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
@@ -1153,10 +1147,6 @@ msgstr "Płynne oświetlenie"
 msgid "Texturing:"
 msgstr "Teksturowanie:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Sterownik OpenGL jest wymagany aby włączyć shadery."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tone Mapping"
@@ -1170,12 +1160,14 @@ msgid "Trilinear Filter"
 msgstr "Filtrowanie trójliniowe"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Ultra High"
-msgstr ""
+msgstr "Bardzo wysokie"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Very Low"
-msgstr ""
+msgstr "Bardzo niskie"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1189,7 +1181,7 @@ msgstr "Fale (Ciecze)"
 msgid "Waving Plants"
 msgstr "Falujące rośliny"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Upłynął czas połączenia."
 
@@ -1218,7 +1210,8 @@ msgid "Connection error (timed out?)"
 msgstr "Błąd połączenia (brak odpowiedzi?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Nie można znaleźć lub wczytać trybu gry \""
 
 #: src/client/clientlauncher.cpp
@@ -1261,14 +1254,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "Adres "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "Tryb kreatywny "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Obrażenia: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Tryb: "
@@ -1290,6 +1275,16 @@ msgstr "Gracz przeciwko graczowi: "
 msgid "- Server Name: "
 msgstr "- Nazwa serwera: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Wystąpił błąd:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Odmowa dostępu. Powód: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automatyczne chodzenie do przodu wyłączone"
@@ -1298,6 +1293,26 @@ msgstr "Automatyczne chodzenie do przodu wyłączone"
 msgid "Automatic forward enabled"
 msgstr "Automatyczne chodzenie do przodu włączone"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds hidden"
+msgstr "Granice bloków"
+
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds shown for all blocks"
+msgstr "Granice bloku pokazane dla wszystkich bloków"
+
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds shown for current block"
+msgstr "Granice bloku wyświetlane dla bieżącego bloku"
+
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds shown for nearby blocks"
+msgstr "Granice bloków pokazane dla pobliskich bloków"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Aktualizowanie kamery wyłączone"
@@ -1306,6 +1321,11 @@ msgstr "Aktualizowanie kamery wyłączone"
 msgid "Camera update enabled"
 msgstr "Aktualizowanie kamery włączone"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Can't show block bounds (need 'basic_debug' privilege)"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Zmień hasło"
@@ -1318,6 +1338,11 @@ msgstr "Tryb kinowy wyłączony"
 msgid "Cinematic mode enabled"
 msgstr "Tryb kinowy włączony"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Modyfikacja klienta"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Skryptowanie po stronie klienta jest wyłączone"
@@ -1326,6 +1351,11 @@ msgstr "Skryptowanie po stronie klienta jest wyłączone"
 msgid "Connecting to server..."
 msgstr "Łączenie z serwerem..."
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Connection failed for unknown reason"
+msgstr "Połączenie nie powiodło się z nieznanego powodu"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Kontynuuj"
@@ -1358,11 +1388,14 @@ msgstr ""
 "- %s: upuść przedmiot↵\n"
 "- %s: otwórz ekwipunek↵\n"
 "- Mysz: obróć się/patrz↵\n"
-"- Lewy przycisk myszy: kop/uderz↵\n"
-"- Prawy przycisk myszy: postaw/użyj↵\n"
 "- Rolka myszy: wybierz przedmiot↵\n"
 "- %s: czatuj↵\n"
 
+#: src/client/game.cpp
+#, fuzzy, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Nie można rozwiązać adresu: %s."
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Tworzenie klienta..."
@@ -1494,7 +1527,7 @@ msgstr "Minimapa aktualnie wyłączona przez grę lub mod"
 #: src/client/game.cpp
 #, fuzzy
 msgid "Multiplayer"
-msgstr "Pojedynczy gracz"
+msgstr "Gra wieloosobowa"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1557,17 +1590,34 @@ msgid "Sound muted"
 msgstr "Głośność wyciszona"
 
 #: src/client/game.cpp
+#, fuzzy
 msgid "Sound system is disabled"
-msgstr ""
+msgstr "System dźwiękowy jest wyłączony"
 
 #: src/client/game.cpp
+#, fuzzy
 msgid "Sound system is not supported on this build"
-msgstr ""
+msgstr "System dźwiękowy nie jest obsługiwany w tej kompilacji"
 
 #: src/client/game.cpp
 msgid "Sound unmuted"
 msgstr "Głośność włączona ponownie"
 
+#: src/client/game.cpp
+#, fuzzy, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Serwer prawdopodobnie pracuje na innej wersji %s."
+
+#: src/client/game.cpp
+#, fuzzy, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Nie można połączyć się z %s, ponieważ IPv6 jest wyłączony"
+
+#: src/client/game.cpp
+#, fuzzy, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Nie można nasłuchiwać na %s, ponieważ IPv6 jest wyłączony"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1901,7 +1951,17 @@ msgstr "Minimapa w trybie powierzchniowym, powiększenie x%d"
 #: src/client/minimap.cpp
 #, fuzzy
 msgid "Minimap in texture mode"
-msgstr "Minimalna wielkość tekstury dla filtrów"
+msgstr "Minimapa w trybie teksturowym"
+
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Pobieranie $1 do $2 nie powiodło się :("
+
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Opening webpage"
+msgstr "Strona początkowa"
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
@@ -1933,7 +1993,7 @@ msgstr "Kontynuuj"
 #: src/gui/guiKeyChangeMenu.cpp
 #, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Specjalny\" = wspinaj się"
+msgstr "\"Specjalny\" = schodź"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1944,16 +2004,18 @@ msgid "Automatic jumping"
 msgstr "Automatyczne skoki"
 
 #: src/gui/guiKeyChangeMenu.cpp
+#, fuzzy
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
 msgstr "Tył"
 
 #: src/gui/guiKeyChangeMenu.cpp
+#, fuzzy
 msgid "Block bounds"
-msgstr ""
+msgstr "Granice bloków"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2076,7 +2138,7 @@ msgstr "Przełącz tryb noclip"
 #: src/gui/guiKeyChangeMenu.cpp
 #, fuzzy
 msgid "Toggle pitchmove"
-msgstr "Przełącz historię czatu"
+msgstr "Przełączanie przemieszczania"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "press key"
@@ -2107,7 +2169,8 @@ msgid "Muted"
 msgstr "Wyciszony"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Głośność: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2139,8 +2202,8 @@ msgid ""
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Użyj wirtualnego joysticka, aby zaaktywować przycisk \"aux\".\n"
-"Gdy włączone, wirtualny joystick również naciśnie przycisk \"aux\", gdy "
+"(Android) Użyj wirtualnego joysticka, aby aktywować przycisk \"aux\".\n"
+"Gdy włączone to wirtualny joystick również naciśnie przycisk \"aux\", gdy "
 "znajduje się poza głównym okręgiem."
 
 #: src/settings_translation_file.cpp
@@ -2208,7 +2271,7 @@ msgstr "Szum 2D, który wpływa na rozmiar/ występowanie stepów górskich."
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "2D noise that locates the river valleys and channels."
-msgstr "Szum 2D, który wpływa na kształt/rozmiar zaokrąglonych wzgórz."
+msgstr "Szum 2D, który wpływa na doliny i kanały rzeczne."
 
 #: src/settings_translation_file.cpp
 msgid "3D clouds"
@@ -2221,7 +2284,7 @@ msgstr "Modele 3D"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "3D mode parallax strength"
-msgstr "Siła map normlanych"
+msgstr "Siła paralaksy w trybie 3D"
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining giant caverns."
@@ -2236,12 +2299,18 @@ msgstr ""
 "Określa również strukturę wznoszącego się terenu górzystego."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "3D noise defining structure of floatlands.\n"
 "If altered from the default, the noise 'scale' (0.7 by default) may need\n"
 "to be adjusted, as floatland tapering functions best when this noise has\n"
 "a value range of approximately -2.0 to 2.0."
 msgstr ""
+"Szum 3D określający strukturę terenów pływających.\n"
+"Jeśli wartość domyślna zostanie zmieniona, konieczne będzie dostosowanie "
+"\"skali\" szumu (domyślnie 0,7), \n"
+"ponieważ zwężanie terenów pływających działa najlepiej, \n"
+"gdy wartość szumu jest z zakresu od około -2,0 do 2,0."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining structure of river canyon walls."
@@ -2306,16 +2375,17 @@ msgstr ""
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "ABM interval"
-msgstr "Interwał zapisu mapy"
+msgstr "Interwał ABM"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "ABM time budget"
-msgstr ""
+msgstr "Budżet czasowy ABM"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Absolute limit of queued blocks to emerge"
-msgstr "Bezwzględny limit kolejki"
+msgstr "Bezwzględny limit kolejki pojawiających się bloków"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration in air"
@@ -2364,7 +2434,13 @@ msgstr ""
 "ekranów 4k."
 
 #: src/settings_translation_file.cpp
-#, c-format
+#, fuzzy
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Dostosuj wykrytą gęstość wyświetlania, używaną do skalowania elementów UI."
+
+#: src/settings_translation_file.cpp
+#, fuzzy, c-format
 msgid ""
 "Adjusts the density of the floatland layer.\n"
 "Increase value to increase density. Can be positive or negative.\n"
@@ -2372,6 +2448,12 @@ msgid ""
 "Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n"
 "to be sure) creates a solid floatland layer."
 msgstr ""
+"Dostosowuje gęstość warstwy pływających wysp.\n"
+"Aby zwiększyć gęstość, ustaw wyższą wartość. Może być dodatnia lub ujemna.\n"
+"Wartość = 0,0: 50% objętości to pływająca wyspa.\n"
+"Wartość = 2,0 (może być wyższa w zależności od 'mgv7_np_floatland', aby mieć "
+"pewność,\n"
+"zawsze sprawdzaj) tworzy stałą warstwę pływającej wyspy."
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
@@ -2473,7 +2555,6 @@ msgstr ""
 "Zapisane w blokach mapy (16 bloków)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatic forward key"
 msgstr "Klawisz automatycznego poruszania się do przodu"
 
@@ -2496,12 +2577,12 @@ msgstr "Tryb automatycznego skalowania"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Aux1 key"
-msgstr "Skok"
+msgstr "Klawisz Aux1"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Klawisz używany do wspinania"
+msgstr "Klawisz Aux1 używany do wspinania/schodzenia"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2554,12 +2635,12 @@ msgstr "Dystans optymalizacji wysyłanych bloków"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Bold and italic font path"
-msgstr "Ścieżka czcionki typu Monospace"
+msgstr "Ścieżka pogrubionej czcionki oraz kursywy"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Bold and italic monospace font path"
-msgstr "Ścieżka czcionki typu Monospace"
+msgstr "Ścieżka pogrubionej czcionki oraz kursywy typu Monospace"
 
 #: src/settings_translation_file.cpp
 msgid "Bold font path"
@@ -2647,21 +2728,28 @@ msgstr "Próg groty"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Cavern upper limit"
-msgstr "Szerokość jaskini"
+msgstr "Górna granica jaskiń"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Center of light curve boost range.\n"
 "Where 0.0 is minimum light level, 1.0 is maximum light level."
 msgstr ""
+"Środek zakresu wzmocnienia krzywej światła.\n"
+"0,0 to minimalny poziom światła, 1,0 to maksymalny poziom światła."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Próg wiadomości wyrzucenia z czatu"
+msgstr "Limit czasu komendy czatu"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
+msgid "Chat commands"
+msgstr "Komenda"
+
+#: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "Rozmiar czcionki"
 
@@ -2672,17 +2760,17 @@ msgstr "Klawisz czatu"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat log level"
-msgstr "Poziom logowania debugowania"
+msgstr "Poziom dziennika czatu"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat message count limit"
-msgstr "Komunikat o stanie połączenia"
+msgstr "Limit liczby wiadomości na czacie"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat message format"
-msgstr "Maksymalna długość wiadomości na czacie"
+msgstr "Format wiadomości czatu"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message kick threshold"
@@ -2697,8 +2785,9 @@ msgid "Chat toggle key"
 msgstr "Klawisz przełączania czatu"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Komenda"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Chat widoczny"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2716,6 +2805,15 @@ msgstr "Klawisz trybu Cinematic"
 msgid "Clean transparent textures"
 msgstr "Czyste przeźroczyste tekstury"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Klikalne łącza internetowe (środkowe kliknięcie lub Ctrl+ kliknięcie lewym "
+"przyciskiem myszy) włączone w wyjściach konsoli czatu."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klient"
@@ -2731,7 +2829,7 @@ msgstr "Modyfikacja klienta"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Client side modding restrictions"
-msgstr "Modyfikacja klienta"
+msgstr "Ograniczenia modowania po stronie klienta"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -2765,9 +2863,10 @@ msgstr "Kolorowa mgła"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Colored shadows"
-msgstr "Kolorowa mgła"
+msgstr "Kolorowe cienie"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Comma-separated list of flags to hide in the content repository.\n"
 "\"nonfree\" can be used to hide packages which do not qualify as 'free "
@@ -2777,6 +2876,13 @@ msgid ""
 "These flags are independent from Minetest versions,\n"
 "so see a full list at https://content.minetest.net/help/content_flags/"
 msgstr ""
+"Oddzielona przecinkami lista flag do ukrycia w repozytorium zawartości.\n"
+"\"nonfree\" mogą być używane do ukrywania pakietów, które nie kwalifikują "
+"się jako \"wolne oprogramowanie\",\n"
+"zgodnie z definicją Fundacji Wolnego Oprogramowania.\n"
+"Można również określić klasyfikacje zawartości.\n"
+"Flagi te są niezależne od wersji Minetesta zobacz, więc pełną listę na "
+"stronie https://content.minetest.net/help/content_flags/"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2798,6 +2904,32 @@ msgstr ""
 msgid "Command key"
 msgstr "Klawisz komend"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Poziom kompresji jaki ma być stosowany przy zapisie bloków map na dysk.\n"
+"-1 - użyj domyślnego poziomu kompresji\n"
+"0 - najmniejsza kompresja, najszybsza\n"
+"9 - najlepsza kompresja, najwolniejsza"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Poziom kompresji jaki ma być użyty podczas wysyłania mapbloków do klienta.\n"
+"-1 - użyj domyślnego poziomu kompresji\n"
+"0 - najmniejsza kompresja, najszybsza\n"
+"9 - najlepsza kompresja, najwolniejsza"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Połączone szkło"
@@ -2827,13 +2959,14 @@ msgid "ContentDB Flag Blacklist"
 msgstr "Flaga czarnej listy ContentDB"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "ContentDB Max Concurrent Downloads"
-msgstr ""
+msgstr "Maksymalna liczba jednoczesnych pobrań ContentDB"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "ContentDB URL"
-msgstr "Zawartość"
+msgstr "Adres URL ContentDB"
 
 #: src/settings_translation_file.cpp
 msgid "Continuous forward"
@@ -2860,9 +2993,9 @@ msgid ""
 "Examples:\n"
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
-"Kontrola długości cyklu dnia i nocy.\n"
-"Przykłady: 72 = 20min, 360 = 4min, 1 = 24hour, 0 = dzień/noc/cokolwiek "
-"zostaje niezmienione."
+"Reguluje długość cyklu dzień/noc.\n"
+"Przykłady:\n"
+"72 = 20min, 360 = 4min, 1 = 24h, 0 = dzień/noc/wszystko pozostaje bez zmian."
 
 #: src/settings_translation_file.cpp
 msgid "Controls sinking speed in liquid."
@@ -2877,11 +3010,15 @@ msgid "Controls steepness/height of hills."
 msgstr "Kontroluje stromość/wysokość gór."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Controls width of tunnels, a smaller value creates wider tunnels.\n"
 "Value >= 10.0 completely disables generation of tunnels and avoids the\n"
 "intensive noise calculations."
 msgstr ""
+"Wpływa na szerokość tuneli, mniejsza wartość tworzy szersze tunele.\n"
+"Wartość >= 10,0 całkowicie wyłącza tworzenie tuneli i pozwala na uniknięcie\n"
+"intensywnych obliczeń hałasu."
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
@@ -2899,7 +3036,7 @@ msgstr "Kanał alfa celownika"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Kanał alfa celownika (pomiędzy 0 a 255).\n"
 "Wpływa również na kolor celownika obiektów"
@@ -2909,10 +3046,13 @@ msgid "Crosshair color"
 msgstr "Kolor celownika"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Crosshair color (R,G,B).\n"
 "Also controls the object crosshair color"
 msgstr ""
+"Kolor celownika (R, G,B).\n"
+"Wpływa również na kolor celownika"
 
 #: src/settings_translation_file.cpp
 msgid "DPI"
@@ -2929,7 +3069,7 @@ msgstr "Klawisz przełączania informacji debugowania"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Debug log file size threshold"
-msgstr "Próg szumu pustyni"
+msgstr "Próg rozmiaru pliku dziennika debugowania"
 
 #: src/settings_translation_file.cpp
 msgid "Debug log level"
@@ -2940,7 +3080,6 @@ msgid "Dec. volume key"
 msgstr "Klawisz zmniejszania głośności"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Decrease this to increase liquid resistance to movement."
 msgstr "Zmniejsz wartość, aby zwiększyć opór ruchu w cieczy."
 
@@ -2979,14 +3118,18 @@ msgstr "Domyślny format raportu"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Default stack size"
-msgstr "Domyślna gra"
+msgstr "Domyślny rozmiar stosu"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Określa jakość filtrowania cieni\n"
+"Symuluje to efekt miękkich cieni, stosując dysk PCF lub poisson\n"
+"ale także zużywa więcej zasobów."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -2999,12 +3142,12 @@ msgstr "Określa obszary z piaszczystymi plażami."
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Defines distribution of higher terrain and steepness of cliffs."
-msgstr "Określa obszary wyższych terenów oraz wpływa na stromość klifów."
+msgstr "Określa rozmieszczenie wyższego terenu i stromość klifów."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Defines distribution of higher terrain."
-msgstr "Określa obszary 'terrain_higher' (szczyt wzgórza)."
+msgstr "Określa rozmieszczenie wyższych terenów."
 
 #: src/settings_translation_file.cpp
 msgid "Defines full size of caverns, smaller values create larger caverns."
@@ -3019,13 +3162,14 @@ msgid "Defines location and terrain of optional hills and lakes."
 msgstr "Określa położenie oraz teren z dodatkowymi górami i jeziorami."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Defines the base ground level."
-msgstr ""
+msgstr "Określa podstawowy poziom podłoża."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Defines the depth of the river channel."
-msgstr "Określa głębokość rzek."
+msgstr "Określa głębokość kanałów rzecznych."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
@@ -3036,10 +3180,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Defines the width of the river channel."
-msgstr "Określa strukturę kanałów rzecznych."
+msgstr "Określa szerokość kanałów rzecznych."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the width of the river valley."
 msgstr "Określa szerokość doliny rzecznej."
 
@@ -3095,7 +3238,7 @@ msgid ""
 "When the 'snowbiomes' flag is enabled, this is ignored."
 msgstr ""
 "Pustynie pojawią się gdy np_biome przekroczy tą wartość.\n"
-"Kiedy nowy system biomu jest odblokowany, ta wartość jest ignorowana."
+"Kiedy flaga 'snowbiomes'  jest włączona,  ta wartość  jest ignorowana."
 
 #: src/settings_translation_file.cpp
 msgid "Desynchronize block animation"
@@ -3104,7 +3247,7 @@ msgstr "Odsynchronizuj animację bloków"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Dig key"
-msgstr "W prawo"
+msgstr "Klawisz kopania"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3118,6 +3261,11 @@ msgstr "Wyłącz anticheat"
 msgid "Disallow empty passwords"
 msgstr "Nie zezwalaj na puste hasła"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Display Density Scaling Factor"
+msgstr "Wyświetl współczynnik skalowania gęstości"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Serwer DNS, wyświetlany na liście serwerów."
@@ -3147,8 +3295,9 @@ msgid "Dungeon minimum Y"
 msgstr "Minimalna wartość Y lochu"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Dungeon noise"
-msgstr ""
+msgstr "Hałas lochu"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3167,10 +3316,25 @@ msgstr ""
 "To wsparcie jest eksperymentalne i API może ulec zmianie."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Włącz filtrowanie dysku poisson.\n"
+"Jeśli włączone, to używa dysku poisson do \"miękkich cieni\". W przeciwnym "
+"razie używa filtrowania PCF."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Enable colored shadows. \n"
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Włącza kolorowe cienie. \n"
+"Na rzeczywistych półprzezroczystych węzłach rzuca kolorowe cienie. To "
+"kosztowne."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3197,13 +3361,6 @@ msgstr "Włącz tryb mod security"
 msgid "Enable players getting damage and dying."
 msgstr "Włącz obrażenia i umieranie graczy."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Włącz losowe wejście użytkownika (tylko dla testowania)."
@@ -3214,10 +3371,13 @@ msgid "Enable register confirmation"
 msgstr "Włącz potwierdzanie rejestracji"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Enable register confirmation when connecting to server.\n"
 "If disabled, new account will be registered automatically."
 msgstr ""
+"Włącz potwierdzanie rejestracji podczas łączenia się z serwerem.\n"
+"Jeśli wyłączone, to nowe konto zostanie zarejestrowane automatycznie."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3277,17 +3437,25 @@ msgid ""
 "Ignored if bind_address is set.\n"
 "Needs enable_ipv6 to be enabled."
 msgstr ""
-"Przełącza pracę serwera w trybie IPv6. Serwer IPv6 może być ograniczony\n"
-"tylko dla klientów IPv6, w zależności od konfiguracji systemu.\n"
-"Ignorowane jeżeli bind_address jest ustawiony."
+"Włącza/wyłącza uruchamianie serwera IPv6.\n"
+"Ignorowane jeśli ustawiony jest bind_address.\n"
+"Wymaga włączenia enable_ipv6."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Enables Hable's 'Uncharted 2' filmic tone mapping.\n"
 "Simulates the tone curve of photographic film and how this approximates the\n"
 "appearance of high dynamic range images. Mid-range contrast is slightly\n"
 "enhanced, highlights and shadows are gradually compressed."
 msgstr ""
+"Umożliwia Hable's 'Uncharted 2' filmowe mapowanie tonów.\n"
+"Symuluje krzywą tonalną kliszy fotograficznej i sposób, w jaki przybliża "
+"ona\n"
+"wygląd obrazów o wysokim zakresie dynamiki. Kontrast w średnim zakresie jest "
+"lekko wzmocniony\n"
+"Wzmocnienie kontrastu w średnich zakresach, stopniowa kompresja świateł i "
+"cieni."
 
 #: src/settings_translation_file.cpp
 msgid "Enables animation of inventory items."
@@ -3302,12 +3470,24 @@ msgid "Enables minimap."
 msgstr "Włącz minimapę."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Enables the sound system.\n"
 "If disabled, this completely disables all sounds everywhere and the in-game\n"
 "sound controls will be non-functional.\n"
 "Changing this setting requires a restart."
 msgstr ""
+"Włącza dźwięk.\n"
+"Jeśli wyłączone, całkowicie wyłącza wszystkie dźwięki wszędzie oraz "
+"sterowanie dźwiękiem \n"
+"w grze nie będzie działać.\n"
+"Zmiana tego ustawienia wymaga ponownego uruchomienia."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
@@ -3318,6 +3498,7 @@ msgid "Entity methods"
 msgstr "Metody bytów"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Exponent of the floatland tapering. Alters the tapering behaviour.\n"
 "Value = 1.0 creates a uniform, linear tapering.\n"
@@ -3326,6 +3507,13 @@ msgid ""
 "Values < 1.0 (for example 0.25) create a more defined surface level with\n"
 "flatter lowlands, suitable for a solid floatland layer."
 msgstr ""
+"Wykładnik zwężenia pływającej wyspy. Zmienia zachowanie zwężenia.\n"
+"Wartość = 1.0 tworzy jednolite, liniowe zwężenie.\n"
+"Wartości > 1.0 tworzą gładkie zwężenie odpowiednie dla domyślnie "
+"odseparowanych\n"
+"floatlands.\n"
+"Wartości < 1.0 (np. 0.25) tworzą bardziej zdefiniowany poziom powierzchni z\n"
+"płaskimi nizinami, odpowiednimi dla jednolitej warstwy pływających wysp."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -3347,7 +3535,7 @@ msgstr "Współczynnik spadku drgań"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Fallback font path"
-msgstr "Zastępcza czcionka"
+msgstr "Ścieżka czcionki zastępczej"
 
 #: src/settings_translation_file.cpp
 msgid "Fast key"
@@ -3366,7 +3554,6 @@ msgid "Fast movement"
 msgstr "Szybkie poruszanie"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
@@ -3383,7 +3570,6 @@ msgid "Field of view in degrees."
 msgstr "Pole widzenia w stopniach."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "File in client/serverlist/ that contains your favorite servers displayed in "
 "the\n"
@@ -3445,36 +3631,37 @@ msgstr "Ustaw wirtualny joystick"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Floatland density"
-msgstr "Gęstość gór na latających wyspach"
+msgstr "Gęstość latających wysp"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Floatland maximum Y"
-msgstr "Maksymalna wartość Y lochu"
+msgstr "Maksymalna wartość Y latających wysp"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Floatland minimum Y"
-msgstr "Minimalna wartość Y lochu"
+msgstr "Minimalna wartość Y latających wysp"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Floatland noise"
-msgstr "Podstawowy szum wznoszącego się terenu"
+msgstr "Szum latających wysp"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Floatland taper exponent"
-msgstr "Gęstość gór na latających wyspach"
+msgstr "Wykładnik zbieżności latających wysp"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Floatland tapering distance"
-msgstr "Podstawowy szum wznoszącego się terenu"
+msgstr "Odległość zwężania latających wysp"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Floatland water level"
-msgstr ""
+msgstr "Poziom wody pływającej wyspy"
 
 #: src/settings_translation_file.cpp
 msgid "Fly key"
@@ -3489,7 +3676,6 @@ msgid "Fog"
 msgstr "Mgła"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Fog start"
 msgstr "Początek mgły"
 
@@ -3498,12 +3684,14 @@ msgid "Fog toggle key"
 msgstr "Klawisz przełączania mgły"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Font bold by default"
-msgstr ""
+msgstr "Domyślnie pogrubiona czcionka"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Font italic by default"
-msgstr ""
+msgstr "Domyślnie kursywa czcionki"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow"
@@ -3518,18 +3706,38 @@ msgid "Font size"
 msgstr "Rozmiar czcionki"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr ""
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Rozmiar domyślnej czcionki w punktach (pt)."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Rozmiar czcionki monospace w punktach (pt)."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Font size of the recent chat text and chat prompt in point (pt).\n"
 "Value 0 will use the default font size."
 msgstr ""
+"Rozmiar czcionki tekstu ostatniej rozmowy i monitu rozmowy w punktach (pt).\n"
+"Wartość 0 spowoduje użycie domyślnego rozmiaru czcionki."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -3600,11 +3808,6 @@ msgstr "Typ fraktalny"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Część widocznej odległości w której mgła zaczyna się renderować"
 
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid "FreeType fonts"
-msgstr "Czcionki Freetype"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3621,6 +3824,7 @@ msgstr ""
 "(16 węzłów)."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "From how far clients know about objects, stated in mapblocks (16 nodes).\n"
 "\n"
@@ -3628,6 +3832,14 @@ msgid ""
 "to maintain active objects up to this distance in the direction the\n"
 "player is looking. (This can avoid mobs suddenly disappearing from view)"
 msgstr ""
+"Maksymalna odległość z której klienci wiedzą o obiektach, podawanych w "
+"blokach map (16 węzłów).\n"
+"\n"
+"Ustawienie wartości większej niż active_block_range spowoduje również, że "
+"serwer\n"
+"będzie utrzymywał aktywne obiekty do tej odległości w kierunku w którym "
+"patrzy gracz. (Dzięki temu można uniknąć nagłego zniknięcia mobów z pola "
+"widzenia)"
 
 #: src/settings_translation_file.cpp
 msgid "Full screen"
@@ -3654,10 +3866,11 @@ msgid "Global callbacks"
 msgstr "Globalne wywołania zwrotne"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Globalne właściwości generowania map.\n"
 "W generatorze map v6 flaga \"decorations\" kontroluje wszystkie dekoracje z "
@@ -3698,12 +3911,12 @@ msgstr "Poziom ziemi"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Ground noise"
-msgstr "Szum błota"
+msgstr "Szum ziemi"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "HTTP mods"
-msgstr "Mody"
+msgstr "Adres HTTP modów"
 
 #: src/settings_translation_file.cpp
 msgid "HUD scale factor"
@@ -3721,11 +3934,11 @@ msgid ""
 "-    log: mimic and log backtrace of deprecated call (default).\n"
 "-    error: abort on usage of deprecated call (suggested for mod developers)."
 msgstr ""
-"Obsługa przestarzałych wywołań lua api:\n"
-"- legacy: (próbuje) naśladuje stare zachowanie (domyślne dla wydań).\n"
-"- log: naśladuje i loguje przestarzałe wywołania (domyślne dla wersji "
-"debug).\n"
-"- error: przerywa kiedy zostanie użyte przestarzałe api (sugerowane dla "
+"Obsługa przestarzałych wywołań API Lua:\n"
+"- brak: nie rejestruje przestarzałych wywołań\n"
+"- log: naśladuje i rejestruje backtrace zdeprecjonowanego wywołania "
+"(domyślnie).\n"
+"- błąd: przerwij przy użyciu przestarzałego wywołania (sugerowane dla "
 "twórców modów)."
 
 #: src/settings_translation_file.cpp
@@ -3753,7 +3966,8 @@ msgstr "Szum gorąca"
 #, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Wysokość początkowego rozmiaru okna."
+msgstr ""
+"Wysokość początkowego rozmiaru okna. Ignorowana w trybie pełnoekranowym."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3774,22 +3988,22 @@ msgstr "Granica zbocza"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hilliness1 noise"
-msgstr "Dźwięk stromości"
+msgstr "Hałas górzystości1"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hilliness2 noise"
-msgstr "Dźwięk stromości"
+msgstr "Hałas górzystości2"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hilliness3 noise"
-msgstr "Dźwięk stromości"
+msgstr "Hałas górzystości3"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hilliness4 noise"
-msgstr "Dźwięk stromości"
+msgstr "Hałas górzystości4"
 
 #: src/settings_translation_file.cpp
 msgid "Homepage of server, to be displayed in the serverlist."
@@ -3833,72 +4047,72 @@ msgstr "Poprzedni klawisz paska działań"
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 1 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 1 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 10 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 10 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 11 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 11 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 12 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 12 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 13 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 13 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 14 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 14 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 15 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 15 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 16 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 16 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 17 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 17 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 18 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 18 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 19 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 19 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 2 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 2 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 20 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 20 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Hotbar slot 21 key"
-msgstr "Następny klawisz paska działań"
+msgstr "Przycisk 21 miejsca paska działań"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -3996,11 +4210,15 @@ msgid "How deep to make rivers."
 msgstr "Jak głębokie tworzyć rzeki."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "How fast liquid waves will move. Higher = faster.\n"
 "If negative, liquid waves will move backwards.\n"
 "Requires waving liquids to be enabled."
 msgstr ""
+"Jak szybko fale cieczy będą się poruszać. Wyższa = szybciej.\n"
+"Wartość ujemna, fale cieczy będą poruszać się do tyłu.\n"
+"Wymaga włączenia falowania cieczy."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4133,25 +4351,40 @@ msgstr ""
 "Pomocne gdy pracujesz na małych powierzchniach."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "If the CSM restriction for node range is enabled, get_node calls are "
 "limited\n"
 "to this distance from the player to the node."
 msgstr ""
+"Jeśli ograniczenie CSM dla zasięgu węzła jest włączone, wywołania get_node "
+"są ograniczone\n"
+"do tej odległości od gracza do węzła."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Jeśli wykonanie polecenia czatu trwa dłużej niż określony czas w sekundach, "
+"dodaj informację o czasie do komunikatu polecenia czatu w\n"
+"sekundach"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "If the file size of debug.txt exceeds the number of megabytes specified in\n"
 "this setting when it is opened, the file is moved to debug.txt.1,\n"
 "deleting an older debug.txt.1 if it exists.\n"
 "debug.txt is only moved if this setting is positive."
 msgstr ""
+"Jeśli rozmiar pliku debug.txt przekroczy liczbę megabajtów określoną w tym "
+"ustawieniu, plik zostanie przeniesiony do pliku debug.txt.1.\n"
+"w tym ustawieniu, plik jest przenoszony do debug.txt.1,\n"
+"usuwając starszy debug.txt.1, jeśli taki istnieje.\n"
+"debug.txt jest przenoszony tylko wtedy, gdy wartość tego ustawienia jest "
+"dodatnia."
 
 #: src/settings_translation_file.cpp
 msgid "If this is set, players will always (re)spawn at the given position."
@@ -4197,7 +4430,8 @@ msgstr ""
 "Najczęściej potrzebny tylko dla osób pracujących nad jądrem"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Instrument poleceń czatu przy rejestracji."
 
 #: src/settings_translation_file.cpp
@@ -4273,12 +4507,17 @@ msgid "Iterations"
 msgstr "Iteracje"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Iterations of the recursive function.\n"
 "Increasing this increases the amount of fine detail, but also\n"
 "increases processing load.\n"
 "At iterations = 20 this mapgen has a similar load to mapgen V7."
 msgstr ""
+"Iteracje funkcji rekursywnej.\n"
+"Zwiększenie tej wartości zwiększa ilość drobnych szczegółów, ale również\n"
+"zwiększa obciążenie przetwarzania.\n"
+"Przy iteracjach = 20 ten mapgen ma podobne obciążenie jak mapgen V7."
 
 #: src/settings_translation_file.cpp
 msgid "Joystick ID"
@@ -4290,7 +4529,7 @@ msgstr "Interwał powtarzania przycisku joysticka"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Typ Joysticka"
 
 #: src/settings_translation_file.cpp
@@ -5159,16 +5398,19 @@ msgid "Large cave depth"
 msgstr "Głębia dużej jaskini"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Large cave maximum number"
-msgstr ""
+msgstr "Maksymalna liczba dużych jaskiń"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Large cave minimum number"
-msgstr ""
+msgstr "Minimalna liczba dużych jaskiń"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Large cave proportion flooded"
-msgstr ""
+msgstr "Duża część jaskini zalana"
 
 #: src/settings_translation_file.cpp
 msgid "Large chat console key"
@@ -5372,12 +5614,14 @@ msgid "Makes all liquids opaque"
 msgstr "Zmienia ciecze w nieprzeźroczyste"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Map Compression Level for Disk Storage"
-msgstr ""
+msgstr "Poziom kompresji mapy dla pamięci masowej dysku"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Map Compression Level for Network Transfer"
-msgstr ""
+msgstr "Poziom kompresji map dla transferu sieciowego"
 
 #: src/settings_translation_file.cpp
 msgid "Map directory"
@@ -5408,6 +5652,7 @@ msgstr ""
 "oceanu, wysp oraz podziemi."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Map generation attributes specific to Mapgen Valleys.\n"
 "'altitude_chill': Reduces heat with altitude.\n"
@@ -5416,6 +5661,13 @@ msgid ""
 "to become shallower and occasionally dry.\n"
 "'altitude_dry': Reduces humidity with altitude."
 msgstr ""
+"Atrybuty generowania mapy specyficzne dla dolin Mapgen.\n"
+"'altitude_chill': Zmniejsza ciepło wraz z wysokością nad poziomem morza.\n"
+"'humid_rivers': Zwiększa wilgotność wokół rzek.\n"
+"'vary_river_depth': Jeżeli włączone, niska wilgotność i wysoka temperatura "
+"powoduje, że rzeki\n"
+"stają się płytsze i czasami wysychają.\n"
+"'altitude_dry': Zmniejsza wilgotność wraz z wysokością."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -5459,7 +5711,7 @@ msgstr "Interwał zapisu mapy"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "Interwał czasowy aktualizacji cieczy"
 
 #: src/settings_translation_file.cpp
@@ -5586,8 +5838,9 @@ msgid "Maximum FPS when the window is not focused, or when the game is paused."
 msgstr "Maksymalny FPS gdy gra spauzowana."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Maksymalna odległość do renderowania cieni."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5599,12 +5852,14 @@ msgid "Maximum hotbar width"
 msgstr "Maksymalna długość hotbar"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Maximum limit of random number of large caves per mapchunk."
-msgstr ""
+msgstr "Maksymalny limit losowej liczby dużych jaskiń na mapchunk."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Maximum limit of random number of small caves per mapchunk."
-msgstr ""
+msgstr "Maksymalny limit losowej liczby małych jaskiń na mapchunk."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -5616,11 +5871,15 @@ msgstr ""
 "z dużą prędkością."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Maximum number of blocks that are simultaneously sent per client.\n"
 "The maximum total count is calculated dynamically:\n"
 "max_total = ceil((#clients + max_users) * per_client / 4)"
 msgstr ""
+"Maksymalna ilość bloków, które są jednocześnie wysyłane na jednego klienta.\n"
+"Maksymalna łączna liczba jest obliczana dynamicznie:\n"
+"max_total = ceil((#clients + max_users) * per_client / 4)"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of blocks that can be queued for loading."
@@ -5646,11 +5905,15 @@ msgstr ""
 "Pozostaw puste a odpowiednia liczba zostanie dobrana automatycznie."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Maximum number of concurrent downloads. Downloads exceeding this limit will "
 "be queued.\n"
 "This should be lower than curl_parallel_limit."
 msgstr ""
+"Maksymalna liczba jednocześnie pobieranych plików. Pobieranie przekraczające "
+"ten limit zostanie umieszczone w kolejce.\n"
+"Powinien być niższy niż curl_parallel_limit."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of forceloaded mapblocks."
@@ -5725,10 +5988,13 @@ msgid ""
 msgstr "Maksymalny czas na pobranie pliku (np.: moda) w ms."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Maksymalny czas, jaki może zająć interaktywne żądanie (np. pobranie listy z "
+"serwera), podany w milisekundach."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5755,8 +6021,9 @@ msgid "Method used to highlight selected object."
 msgstr "Metoda użyta do podświetlenia wybranego obiektu."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Minimal level of logging to be written to chat."
-msgstr ""
+msgstr "Minimalny poziom logowania, który ma być zapisywany na czacie."
 
 #: src/settings_translation_file.cpp
 msgid "Minimap"
@@ -5776,8 +6043,9 @@ msgid "Minimum limit of random number of large caves per mapchunk."
 msgstr "Szum 3D, który wpływa na liczbę lochów na jeden mapchunk."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Minimum limit of random number of small caves per mapchunk."
-msgstr ""
+msgstr "Minimalny limit losowej liczby małych jaskiń na mapchunk."
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -5793,7 +6061,8 @@ msgid "Mod channels"
 msgstr "Kanały modów"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "Modyfikuje rozmiar elementów paska HUD."
 
 #: src/settings_translation_file.cpp
@@ -5804,6 +6073,11 @@ msgstr "Ścieżka czcionki typu Monospace"
 msgid "Monospace font size"
 msgstr "Rozmiar czcionki Monospace"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Rozmiar czcionki Monospace"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Szum wysokości góry"
@@ -5851,12 +6125,17 @@ msgid "Mute sound"
 msgstr "Wycisz dźwięk"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Name of map generator to be used when creating a new world.\n"
 "Creating a world in the main menu will override this.\n"
 "Current mapgens in a highly unstable state:\n"
 "-    The optional floatlands of v7 (disabled by default)."
 msgstr ""
+"Nazwa generatora map, który ma być użyty podczas tworzenia nowego świata.\n"
+"Tworzenie świata w menu głównym nadpisze tę wartość.\n"
+"Obecne mapgeny są w bardzo niestabilnym stanie:\n"
+"- Opcjonalne floatlands z v7 (domyślnie wyłączone)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5920,6 +6199,7 @@ msgid "Number of emerge threads"
 msgstr "Liczba powstających wątków"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of emerge threads to use.\n"
 "Value 0:\n"
@@ -5932,11 +6212,24 @@ msgid ""
 "processes, especially in singleplayer and/or when running Lua code in\n"
 "'on_generated'. For many users the optimum setting may be '1'."
 msgstr ""
+"Ilość wątków emerge do wykorzystania.\n"
+"Wartość 0:\n"
+"- Wybór automatyczny. Liczba wątków emerge będzie wynosić\n"
+"- 'liczba procesorów - 2', z dolną granicą 1.\n"
+"Dowolna inna wartość:\n"
+"- Określa liczbę wątków emerge, z dolnym limitem równym 1.\n"
+"OSTRZEŻENIE: Zwiększenie liczby wątków emerge zwiększa szybkość mapgena "
+"silnika,\n"
+"ale może to wpłynąć na wydajność gry przez zakłócanie innych\n"
+"procesami, szczególnie w grze dla pojedynczego gracza i/lub podczas "
+"uruchamiania kodu Lua w\n"
+"'on_generated'. Dla wielu użytkowników optymalnym ustawieniem może być '1'."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Ilość dodatkowych bloków, które mogą zostać wczytane naraz przez /"
@@ -5954,9 +6247,12 @@ msgid "Opaque liquids"
 msgstr "Nieprzeźroczyste ciecze"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Opaqueness (alpha) of the shadow behind the default font, between 0 and 255."
 msgstr ""
+"Nieprzezroczystość (alfa) cienia za domyślną czcionką, w zakresie od 0 do "
+"255."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5968,19 +6264,33 @@ msgstr ""
 "formspec jest otwarty."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Optional override for chat weblink color."
+msgstr "Opcjonalna zmiana koloru łącza internetowego czatu."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
+"Ścieżka do czcionki awaryjnej.\n"
+"Jeśli ustawienie \"freetype\" jest włączone: Musi być czcionką TrueType.\n"
+"Jeśli ustawienie \"freetype\" jest wyłączone: Musi być czcionką bitmapową "
+"lub wektorową XML.\n"
+"Ta czcionka będzie używana dla niektórych języków lub jeśli domyślna "
+"czcionka jest niedostępna."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Path to save screenshots at. Can be an absolute or relative path.\n"
 "The folder will be created if it doesn't already exist."
 msgstr ""
+"Ścieżka w której zapisywane są zrzuty ekranu. Może być bezwzględna lub "
+"względna.\n"
+"Folder zostanie utworzony, jeśli jeszcze nie istnieje."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5997,28 +6307,37 @@ msgstr ""
 "wyszukiwane z tej lokalizacji."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
+"Ścieżka do domyślnej czcionki.\n"
+"Jeśli włączone jest ustawienie \"freetype\": Musi być czcionką TrueType.\n"
+"Jeśli ustawienie \"freetype\" jest wyłączone: Musi być czcionką bitmapową "
+"lub wektorową XML.\n"
+"Czcionka awaryjna zostanie użyta, jeśli nie może zostać załadowana."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
+"Ścieżka do czcionki monospace.\n"
+"Jeśli włączone jest ustawienie \"freetype\": Musi być czcionką TrueType.\n"
+"Jeśli ustawienie \"freetype\" jest wyłączone: Musi być czcionką bitmapową "
+"lub wektorową XML.\n"
+"Ta czcionka jest używana np. w konsoli i na ekranie profilera."
 
 #: src/settings_translation_file.cpp
 msgid "Pause on lost window focus"
 msgstr "Pauza, gdy okno jest nieaktywne"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Per-player limit of queued blocks load from disk"
-msgstr ""
+msgstr "Limit załadowanych bloków z dysku na jednego gracza"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -6126,20 +6445,27 @@ msgid "Profiling"
 msgstr "Profilowanie modyfikacji"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Prometheus listener address"
-msgstr ""
+msgstr "Adres słuchacza Prometheusa"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
+"Adres listenera Prometheus.\n"
+"Jeśli Minetest jest skompilowany z włączoną opcją ENABLE_PROMETHEUS,\n"
+"włącz słuchanie metryk dla Prometheusa na tym adresie.\n"
+"Metryki mogą być pobierane na stronie http://127.0.0.1:30000/metrics"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Proportion of large caves that contain liquid."
-msgstr ""
+msgstr "Proporcja dużych jaskiń, które zawierają ciecz."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6471,32 +6797,37 @@ msgstr ""
 "Ustaw maksymalny ciąg znaków wiadomości czatu wysyłanych przez klientów."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
+"Ustaw siłę cienia.\n"
+"Niższa wartość oznacza jaśniejsze cienie, wyższa wartość oznacza ciemniejsze "
+"cienie."
 
 #: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
-#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Ustaw rozmiar zasięgu gładkiego cienia.\n"
+"Niższe wartości oznaczają ostrzejsze cienie, wyższe wartości oznaczają "
+"gładsze cienie.\n"
+"Minimalna wartość: 1.0; maksymalna wartość: 10.0"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Ustaw nachylenie orbity Słońca/Księżyca w stopniach.\n"
+"Wartość 0 oznacza brak nachylenia / orbitę pionową.\n"
+"Wartość minimalna: 0.0; wartość maksymalna: 60.0"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -6535,11 +6866,15 @@ msgstr ""
 "Wymaga shaderów."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Sets shadow texture quality to 32 bits.\n"
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Ustawia jakość tekstury cienia na 32 bity.\n"
+"Jeśli wartość jest fałszywa, używana będzie tekstura 16-bitowa.\n"
+"Może to powodować znacznie więcej artefaktów w cieniu."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6562,12 +6897,14 @@ msgid "Shadow filter quality"
 msgstr "Jakość zrzutu ekranu"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Maksymalna odległość mapy cieni w węzłach do renderowania cieni"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Tekstura mapy cieni w 32 bitach"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -6582,8 +6919,9 @@ msgid ""
 msgstr "Offset cienia czcionki, jeżeli 0 to cień nie będzie rysowany."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "Shadow strength"
-msgstr ""
+msgstr "Siła cienia"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6607,8 +6945,9 @@ msgstr ""
 "Wymagany restart po zmianie ustawienia."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
-msgstr ""
+#, fuzzy
+msgid "Show name tag backgrounds by default"
+msgstr "Domyślnie wyświetlaj tła znaczników imiennych"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6726,6 +7065,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid ""
@@ -6850,7 +7197,7 @@ msgstr "Paczki tekstur"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6870,7 +7217,7 @@ msgstr "Adres URL repozytorium zawartości"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "Identyfikator użycia joysticka"
 
 #: src/settings_translation_file.cpp
@@ -6944,9 +7291,10 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr "Czułość osi joysticka, wpływa na drgania widoku."
 
 #: src/settings_translation_file.cpp
@@ -7060,6 +7408,10 @@ msgstr "Opóźnienie wskazówek narzędzi"
 msgid "Touch screen threshold"
 msgstr "Próg ekranu dotykowego"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Szum drzew"
@@ -7139,8 +7491,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Włącz filtrowanie bilinearne podczas skalowania tekstur."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7349,6 +7702,11 @@ msgstr "Długość fal wodnych"
 msgid "Waving plants"
 msgstr "Falujące rośliny"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Kolor zaznaczenia"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7379,7 +7737,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7398,18 +7756,8 @@ msgstr ""
 "przypisanych dla świata przy autoskalowaniu tekstur."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Kiedy tylko czcionki wolnego typu są używane wymagana jest ich kompilacja "
-"wspierająca takie czcionki."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7550,24 +7898,6 @@ msgstr "Wysokość dolin oraz dna jezior."
 msgid "Y-level of seabed."
 msgstr "Wysokość dna jezior."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL przekroczono limit pobierania pliku"
@@ -7581,6 +7911,12 @@ msgstr "Limit czasu cURL"
 msgid "cURL parallel limit"
 msgstr "Limit równoległy cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "Tryb kreatywny "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Obrażenia: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7749,6 +8085,9 @@ msgstr "Limit równoległy cURL"
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "Kanał alfa cienia czcionki (nieprzeźroczystość, od 0 do 255)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Czcionki Freetype"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Głębia koloru w trybie pełnoekranowym"
 
@@ -7767,6 +8106,9 @@ msgstr "Limit równoległy cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "Wsparcie IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Zainstaluj mod: plik: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "Głębia dużej jaskini"
@@ -7896,6 +8238,9 @@ msgstr "Limit równoległy cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Ta czcionka zostanie użyta w niektórych językach."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Sterownik OpenGL jest wymagany aby włączyć shadery."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Przełącz na tryb Cinematic"
 
@@ -7916,6 +8261,15 @@ msgstr "Limit równoległy cURL"
 #~ msgid "Waving water"
 #~ msgstr "Falująca woda"
 
+#, fuzzy
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Kiedy tylko czcionki wolnego typu są używane wymagana jest ich kompilacja "
+#~ "wspierająca takie czcionki."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Określa czy lochy mają być czasem przez generowane teren."
 
@@ -7932,5 +8286,8 @@ msgstr "Limit równoległy cURL"
 #~ msgid "Yes"
 #~ msgstr "Tak"
 
+#~ msgid "You died."
+#~ msgstr "Umarłeś."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 63f7ec39cd4efbdbc8b41569ca1545a1b37d691a..d403ad5d494b8f0ad03d204071d97eb72a92bb54 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Portuguese (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-05-10 16:33+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-04 06:53+0000\n"
 "Last-Translator: ssantos <ssantos@web.de>\n"
 "Language-Team: Portuguese <https://hosted.weblate.org/projects/minetest/"
 "minetest/pt/>\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Tamanho máximo da fila do chat"
+msgstr "Limpe a fila de espera do chat"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Comandos do Chat"
+msgstr "Comando vazio."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Sair para o Menu"
+msgstr "Sair para o menu principal"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Comandos do Chat"
+msgstr "Comando inválido: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Comando emitido: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Um Jogador"
+msgstr "Liste os jogadores online"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Um Jogador"
+msgstr "Jogadores online: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "A fila de espera do chat agora está vazia."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Este comando está desativado pelo servidor."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,41 @@ msgstr "Renascer"
 msgid "You died"
 msgstr "Você morreu"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Você morreu"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Comandos do Chat"
+msgstr "Comandos disponíveis:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Comandos do Chat"
+msgstr "Comandos disponíveis: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Comando não disponível: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Obtenha ajuda para comandos"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Use '.help <cmd>' para conseguir mais informação, ou '.help all' para listar "
+"tudo."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all| <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<Comando não disponível>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Um erro ocorreu num script Lua:"
@@ -303,6 +296,10 @@ msgstr "Instalar $1"
 msgid "Install missing dependencies"
 msgstr "Instalar dependências ausentes"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Instalação: Tipo de arquivo não suportado ou corrompido"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -632,7 +629,7 @@ msgid "Offset"
 msgstr "Deslocamento"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Persistência"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -745,14 +742,6 @@ msgstr ""
 "Instalação do Mod: não foi possível encontrar o nome da pasta adequado para "
 "o modpack $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Instalar: Tipo de ficheiro \"$1\" não suportado ou corrompido"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instalar: ficheiro: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Incapaz de encontrar um módulo ou modpack válido"
@@ -789,16 +778,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Sobre"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Contribuidores Ativos"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Distância de envio de objetos ativos"
+msgstr "Renderizador ativo:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -933,9 +921,8 @@ msgid "Start Game"
 msgstr "Iniciar o jogo"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Endereço: "
+msgstr "Endereço"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -951,22 +938,20 @@ msgstr "Modo Criativo"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Ativar dano"
+msgstr "Dano / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Rem. Favorito"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favorito"
+msgstr "Favoritos"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Servidores incompatíveis"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -977,16 +962,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Anunciar servidor"
+msgstr "Servidores Públicos"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Atualizar"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Descrição do servidor"
 
@@ -1031,13 +1014,12 @@ msgid "Connected Glass"
 msgstr "Vidro conectado"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Sombra da fonte"
+msgstr "Sombras dinâmicas"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Sombras dinâmicas: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1045,15 +1027,15 @@ msgstr "Folhas detalhadas"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Baixo"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Médio"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1127,10 +1109,6 @@ msgstr "Iluminação Suave"
 msgid "Texturing:"
 msgstr "Texturização:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Para ativar as sombras é necessário usar o controlador OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Mapeamento de tons"
@@ -1145,11 +1123,11 @@ msgstr "Filtro trilinear"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Muito Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Muito Baixo"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1163,7 +1141,7 @@ msgstr "Líquidos ondulantes"
 msgid "Waving Plants"
 msgstr "Plantas ondulantes"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Erro de ligação (tempo excedido)."
 
@@ -1192,8 +1170,8 @@ msgid "Connection error (timed out?)"
 msgstr "Erro de ligação (excedeu tempo?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Não foi possível encontrar ou carregar jogo \""
+msgid "Could not find or load game"
+msgstr "Não foi possível localizar ou carregar jogo "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1235,14 +1213,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Endereço: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "Modo Criativo: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "-Dano: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Modo: "
@@ -1264,6 +1234,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "Nome do servidor: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Ocorreu um erro:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Acesso negado. Razão:%s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Avanço automático desativado"
@@ -1272,6 +1251,22 @@ msgstr "Avanço automático desativado"
 msgid "Automatic forward enabled"
 msgstr "Avanço automático para frente ativado"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Limites de bloco ocultos"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Limites de bloco mostrados para todos os blocos"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Limites de bloco mostrados para o bloco atual"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Limites de bloco mostrados para blocos próximos"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Atualização da camera desativada"
@@ -1280,6 +1275,10 @@ msgstr "Atualização da camera desativada"
 msgid "Camera update enabled"
 msgstr "Atualização da camera habilitada"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Mudar palavra-passe"
@@ -1292,6 +1291,10 @@ msgstr "Modo cinemático desativado"
 msgid "Cinematic mode enabled"
 msgstr "Modo cinemático ativado"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Cliente desconectado"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "O scripting de cliente está desativado"
@@ -1300,6 +1303,10 @@ msgstr "O scripting de cliente está desativado"
 msgid "Connecting to server..."
 msgstr "A conectar ao servidor..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "A conexão falhou por motivo desconhecido"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Continuar"
@@ -1337,6 +1344,11 @@ msgstr ""
 "- Roda do rato: selecionar item\n"
 "- %s: bate-papo\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Não foi possível resolver o endereço:%s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "A criar cliente..."
@@ -1466,9 +1478,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Minipapa atualmente desativado por jogo ou mod"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Um Jogador"
+msgstr "Multi-jogador"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1542,6 +1553,21 @@ msgstr "Som do sistema não é suportado nesta versão"
 msgid "Sound unmuted"
 msgstr "Som desmutado"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "O servidor provavelmente está executando uma versão diferente de%s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Não foi possível conectar a%s porque o IPv6 está desativado"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Incapaz de escutar em%s porque IPv6 está desativado"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1876,6 +1902,14 @@ msgstr "Minimapa em modo de superfície, ampliação %dx"
 msgid "Minimap in texture mode"
 msgstr "Minimapa em modo de textura"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Falha ao abrir página da web"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Abrindo página da web"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "As palavra-passes não correspondem!"
@@ -1905,7 +1939,6 @@ msgid "Proceed"
 msgstr "Continuar"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
 msgstr "\"Especial\" = descer"
 
@@ -1919,7 +1952,7 @@ msgstr "Pulo automático"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Especial"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1927,7 +1960,7 @@ msgstr "Recuar"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Limites de bloco"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2078,8 +2111,9 @@ msgid "Muted"
 msgstr "Mutado"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Volume do som: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Volume do som: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2104,15 +2138,14 @@ msgstr ""
 "toque."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Use joystick virtual para ativar botão \"aux\".\n"
-"Se ativado, o joystick virtual vai também clicar no botão \"aux\" quando "
-"estiver fora do círculo principal."
+"(Android) Use joystick virtual para ativar botão \"especial\".\n"
+"Se ativado, o joystick virtual vai também clicar no botão \"especial\" "
+"quando estiver fora do circulo principal."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2338,6 +2371,12 @@ msgstr ""
 "Ajustar configuração de dpi ao seu ecrã (não aplicável a X11/Android) ex: "
 "para ecrãs 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Ajuste a densidade de exibição detectada, usada para dimensionar os "
+"elementos da IU."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2474,14 +2513,12 @@ msgid "Autoscaling mode"
 msgstr "Modo de alto escalamento"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Tecla de saltar"
+msgstr "Tecla especial"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Tecla especial pra escalar/descer"
+msgstr "Tecla Aux1 pra escalar/descer"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2632,9 +2669,12 @@ msgstr ""
 "0,0 é o nível mínimo de luz, 1,0 é o nível máximo de luz."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Limite da mensagem de expulsão"
+msgstr "Limite de mensagem de tempo de comando de bate-papo"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Comandos de Chat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2669,8 +2709,8 @@ msgid "Chat toggle key"
 msgstr "Tecla mostra/esconde conversação"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Comandos do Chat"
+msgid "Chat weblinks"
+msgstr "Ligações de bate-papo"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2688,6 +2728,14 @@ msgstr "Tecla para modo cinematográfico"
 msgid "Clean transparent textures"
 msgstr "Limpar texturas transparentes"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Ligações da web clicáveis (clique do meio ou Ctrl + botão esquerdo) ativados "
+"na saída do console de bate-papo."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Cliente"
@@ -2733,9 +2781,8 @@ msgid "Colored fog"
 msgstr "Névoa colorida"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Névoa colorida"
+msgstr "Sombra colorida"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2778,6 +2825,35 @@ msgstr ""
 msgid "Command key"
 msgstr "Tecla de comando"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Nível de compressão ZLib a ser usada ao gravar mapblocks no disco.\n"
+"-1 - Nível de compressão padrão do Zlib\n"
+"0 - Nenhuma compressão; o mais rápido\n"
+"9 - Melhor compressão; o mais devagar\n"
+"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
+"normal)"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Nível de compressão ZLib a ser usada ao mandar mapblocks para o cliente.\n"
+"-1 - Nível de compressão padrão do Zlib\n"
+"0 - Nenhuma compressão; o mais rápido\n"
+"9 - Melhor compressão; o mais devagar\n"
+"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
+"normal)"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Vidro conectado"
@@ -2878,10 +2954,10 @@ msgstr "Opacidade do cursor"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
-"fAlpha do cursor (o quanto ele é opaco, níveis entre 0 e 255).\n"
-"Também controla a cor da cruz do objeto"
+"Alpha do cursor (quanto ele é opaco, níveis entre 0 e 255).\n"
+"Também controla a cor da cruz do objeto."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2961,10 +3037,13 @@ msgstr "Tamanho de pilha predefinido"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Define a qualidade de filtragem de sombreamento\n"
+"Isso simula um efeito de sombras suaves aplicando um PCF ou um Poisson disk\n"
+"mas também usa mais recursos."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3093,6 +3172,10 @@ msgstr "Desativar anti-batota"
 msgid "Disallow empty passwords"
 msgstr "Não permitir palavra-passes vazias"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Nome de domínio do servidor, para ser mostrado na lista de servidores."
@@ -3143,9 +3226,22 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Ativa filtragem de Poisson disk.\n"
+"Quando em true usa o Poisson disk para fazer \"sombras suaves\". Caso "
+"contrário, usa filtragem PCF."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Ativa sombras coloridas.\n"
+"Quando em true, nodes translúcidos podem projetar sombras coloridas. Requer "
+"o uso de muitos recursos."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3171,13 +3267,6 @@ msgstr "Ativar segurança de extras"
 msgid "Enable players getting damage and dying."
 msgstr "Ativar dano e morte dos jogadores."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Ativa a entrada de comandos aleatória (apenas usado para testes)."
@@ -3291,6 +3380,12 @@ msgstr ""
 "os controles de som no jogo não funcionarão.\n"
 "A alteração desta configuração requer um reinício."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Intervalo de exibição dos dados das analizes do motor"
@@ -3356,12 +3451,11 @@ msgid "Fast movement"
 msgstr "Modo rápido"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Movimento rápido (através da tecla \"especial\").\n"
+"Movimento rápido (através da tecla \"Aux1\").\n"
 "Isso requer o privilegio \"fast\" no servidor."
 
 #: src/settings_translation_file.cpp
@@ -3394,7 +3488,6 @@ msgid "Filmic tone mapping"
 msgstr "Mapeamento de tom fílmico"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3403,8 +3496,9 @@ msgid ""
 msgstr ""
 "Texturas filtradas podem misturar valores RGB com os vizinhos totalmente \n"
 "transparentes, o qual otimizadores PNG geralmente descartam, por vezes \n"
-"resultando em uma linha escura em texturas transparentes.\n"
-"Aplicar esse filtro para limpar isso no tempo de carregamento da textura."
+"resultando numa linha escura em texturas transparentes.\n"
+"Aplique esse filtro para limpar isso no momento de carregamento da textura.\n"
+"Esse filtro será ativo automaticamente ao ativar \"mipmapping\"."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3496,11 +3590,17 @@ msgid "Font size"
 msgstr "Tamanho da fonte"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Tamanho da fonte predefinida em pontos (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Tamanho da fonte de largura fixa em pontos (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3512,6 +3612,17 @@ msgstr ""
 "pontos (pt).\n"
 "O valor 0 irá utilizar o tamanho padrão de fonte."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3575,10 +3686,6 @@ msgstr "Tipo fractal"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Fração da distância visível em que a névoa começa a aparecer"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Fontes Freetype"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3635,10 +3742,10 @@ msgstr "Chamadas de retorno Globais"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Atributos de geração de mapa globais.\n"
-"No gerador de mapa v6 a flag 'decorations' controla todas as decorações "
+"No gerador de mapa v6 a flag 'decorations' controla todas as decorações, "
 "exceto árvores\n"
 "e gramas da selva, em todos os outros geradores de mapa essa flag controla "
 "todas as decorações."
@@ -3723,10 +3830,11 @@ msgid "Heat noise"
 msgstr "Ruído para cavernas #1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Altura da janela inicial."
+msgstr ""
+"Componente de altura do tamanho da janela inicial. Ignorado em modo de ecrã "
+"cheio."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3980,13 +4088,13 @@ msgstr ""
 "para não gastar a potência da CPU desnecessariamente."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Se estiver desativado, a tecla \"especial será usada para voar rápido se "
-"modo voo e rápido estiverem ativados."
+"Se estiver desativado, a tecla \"especial\" será usada para voar rápido se "
+"modo voo e rápido estiverem\n"
+"ativados."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4015,13 +4123,12 @@ msgstr ""
 "Isto requer o privilégio \"noclip\" no servidor."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Se ativado, a tecla \"especial\" em vez de \"esgueirar\" servirá para usada "
+"Se ativado, a tecla \"especial\" em vez de \"esgueirar\" servirá para\n"
 "descer."
 
 #: src/settings_translation_file.cpp
@@ -4082,6 +4189,9 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Se a execução de um comando de chat demorar mais do que o tempo especificado "
+"em\n"
+"segundos, adicione a informação do tempo na mensagem-comando"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4143,7 +4253,8 @@ msgstr ""
 "Isto é usualmente apenas nessesário por contribuidores core/builtin"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Monitoração de comandos de chat quando registrados."
 
 #: src/settings_translation_file.cpp
@@ -4238,7 +4349,7 @@ msgid "Joystick button repetition interval"
 msgstr "Intervalo de repetição do botão do Joystick"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "\"Zona morta\" do joystick"
 
 #: src/settings_translation_file.cpp
@@ -5350,7 +5461,7 @@ msgstr "Intervalo de salvamento de mapa"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "Período de atualização dos Líquidos"
 
 #: src/settings_translation_file.cpp
@@ -5601,19 +5712,20 @@ msgstr ""
 "0 para desativar a fila e -1 para a tornar ilimitada."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Tempo máximo em ms para descarregamento de ficheiro (por exemplo, um "
-"ficheiro ZIP de um modificador) pode tomar."
+"Tempo máximo em ms para descarregar ficheiros (por exemplo, um mod) pode "
+"tomar."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Tempo máximo que um pedido interativo (ex: busca de lista de servidores) "
+"pode levar, em milissegundos."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5678,7 +5790,7 @@ msgid "Mod channels"
 msgstr "Canais de mod"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr "Modifica o tamanho dos elementos do hudbar."
 
 #: src/settings_translation_file.cpp
@@ -5689,6 +5801,11 @@ msgstr "Caminho de fonte monoespaçada"
 msgid "Monospace font size"
 msgstr "Tamanho da fonte monoespaçada"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Tamanho da fonte monoespaçada"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Parâmetros ruido da altura de montagem do gerador de mundo v7"
@@ -5838,13 +5955,13 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
-"Número de blocos extras que pode ser carregados por /clearobjects ao mesmo "
-"tempo.\n"
-"Esta é uma troca entre sobrecarga de transação do sqlite e consumo de "
-"memória (4096 = 100 MB, como uma regra de ouro)."
+"Quantidde de blocos adicionais que podem ser carregados por /clearobjects ao "
+"mesmo tempo.\n"
+"Esta é uma troca entre sobrecarga de transação do sqlite e\n"
+"consumo de memória (4096 = 100 MB, como uma regra de ouro)."
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
@@ -5869,10 +5986,13 @@ msgstr ""
 "formspec está aberto."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Substituição opcional da cor de ligações do bate-papo."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5906,10 +6026,9 @@ msgstr ""
 "primeiro daqui."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Caminho para a fonte padrão.\n"
@@ -5919,10 +6038,9 @@ msgstr ""
 "A fonte alternativa será usada se não for possível carregar essa."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Caminho para a fonte monoespaçada.\n"
@@ -5985,9 +6103,8 @@ msgid "Player versus player"
 msgstr "Jogador contra jogador"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Filtro bi-linear"
+msgstr "Filtragem de Poisson"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6042,9 +6159,9 @@ msgstr "Endereço do Prometheus"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Endereço do Prometheus\n"
 "Se o minetest for compilado com a opção ENABLE_PROMETHEUS ativa,\n"
@@ -6387,37 +6504,38 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Defina a força da sombra.\n"
+"Valores mais baixo significam sombras mais brandas, valores mais altos "
+"significam sombras mais fortes."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Defina o tamanho do raio de sombras suaves.\n"
+"Valores mais baixos significam sombras mais nítidas e valores altos sombras "
+"suaves.\n"
+"Valor mínimo 1.0 e valor máximo 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Defina a inclinação da órbita do Sol/Lua em graus\n"
+"Valor 0 significa sem inclinação/ órbita vertical.\n"
+"Valor mínimo de 0.0 e máximo de 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Definido como true ativa o balanço das folhas.\n"
-"Requer que os sombreadores estejam ativados."
+"Defina para true para ativar o Mapeamento de Sombras.\n"
+"Requer sombreadores para ser ativado."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6449,6 +6567,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Define a qualidade da textura das sombras para 32 bits.\n"
+"Quando false, a textura de 16 bits será usada\n"
+"Isso pode fazer com que muito mais coisas aparecam nas sombras."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6466,22 +6587,20 @@ msgstr ""
 "Só funcionam com o modo de vídeo OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Qualidade da Captura de ecrã"
+msgstr "Qualidade do filtro de sombras"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Distância do mapa de sombras em nodes para renderizar sombras"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Textura do mapa de sombras em 32 bits"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Tamanho mínimo da textura"
+msgstr "Tamanho da textura do mapa de sombras"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6493,7 +6612,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Força da sombra"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6516,9 +6635,8 @@ msgstr ""
 "É necessário reiniciar após alterar isso."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Show nametag backgrounds by default"
-msgstr "Fonte em negrito por predefinição"
+msgid "Show name tag backgrounds by default"
+msgstr "Mostrar plano de fundo da nametag por padrão"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6551,7 +6669,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Inclinação Da Órbita Do Céu"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6613,9 +6731,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Velocidade furtiva, em nós por segundo."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Opacidade da sombra da fonte"
+msgstr "Raio das sombras suaves"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6644,6 +6761,14 @@ msgstr ""
 "Note que mods e games talvez definam explicitamente um tamanho para certos "
 "(ou todos) os itens."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6780,8 +6905,11 @@ msgstr "Caminho para a pasta de texturas"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Tamanho da textura em que o mapa de sombras será renderizado em.\n"
+"Deve ser um múltiplo de dois.\n"
+"Números maiores criam sombras melhores mas também esvazia a conta do banco."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6805,7 +6933,7 @@ msgid "The URL for the content repository"
 msgstr "A url para o repositório de conteúdo"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "A zona morta do joystick"
 
 #: src/settings_translation_file.cpp
@@ -6881,7 +7009,6 @@ msgstr ""
 "Isso deve ser configurado junto com active_object_send_range_blocks."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6890,7 +7017,7 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"O back-end de renderização para Irrlicht.\n"
+"O back-end de renderização.\n"
 "É necessário reiniciar após alterar isso.\n"
 "Nota: No Android, use OGLES1 se não tiver certeza! A app pode falhar ao "
 "iniciar de outra forma.\n"
@@ -6898,9 +7025,10 @@ msgstr ""
 "Shaders são suportados por OpenGL (somente desktop) e OGLES2 (experimental)"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "A sensibilidade dos eixos do joystick para movimentar o \n"
 "frustum de exibição no jogo."
@@ -7020,6 +7148,10 @@ msgstr "Atraso de dica de ferramenta"
 msgid "Touch screen threshold"
 msgstr "Limiar o ecrã de toque"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Ruido de árvores"
@@ -7098,8 +7230,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Usar filtragem bilinear ao dimensionamento de texturas."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7231,9 +7364,8 @@ msgid "Viewing range"
 msgstr "Intervalo de visualização"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Joystick virtual ativa botão auxiliar"
+msgstr "Joystick virtual ativa botão especial"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7309,6 +7441,11 @@ msgstr "Comprimento de balanço da água"
 msgid "Waving plants"
 msgstr "Balançar das Plantas"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Cor da caixa de seleção"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7338,7 +7475,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7358,17 +7495,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Se as fontes FreeType são usadas, requer que suporte FreeType tenha sido "
-"compilado.\n"
-"Se desativado, fontes de bitmap e de vetores XML são usadas em vez disso."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7425,9 +7552,9 @@ msgstr ""
 "premir F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Largura da janela inicial."
+msgstr ""
+"Componente de tamanho da janela inicial. Ignorado em modo de ecrã cheio."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7530,36 +7657,6 @@ msgstr "Nível Y de terreno inferior e solo oceânico."
 msgid "Y-level of seabed."
 msgstr "Nível Y do fundo do mar."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Nível de compressão ZLib a ser usada ao gravar mapblocks no disco.\n"
-"-1 - Nível de compressão padrão do Zlib\n"
-"0 - Nenhuma compressão; o mais rápido\n"
-"9 - Melhor compressão; o mais devagar\n"
-"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
-"normal)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Nível de compressão ZLib a ser usada ao mandar mapblocks para o cliente.\n"
-"-1 - Nível de compressão padrão do Zlib\n"
-"0 - Nenhuma compressão; o mais rápido\n"
-"9 - Melhor compressão; o mais devagar\n"
-"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
-"normal)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Tempo limite de descarregamento de ficheiro via cURL"
@@ -7573,6 +7670,12 @@ msgstr "Tempo limite de cURL"
 msgid "cURL parallel limit"
 msgstr "limite paralelo de cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "Modo Criativo: "
+
+#~ msgid "- Damage: "
+#~ msgstr "-Dano: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7753,6 +7856,9 @@ msgstr "limite paralelo de cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Tamanho da fonte reserva em pontos (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Fontes Freetype"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP em ecrã inteiro"
 
@@ -7771,6 +7877,9 @@ msgstr "limite paralelo de cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "Suporte IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instalar: ficheiro: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Profundidade da lava"
 
@@ -7902,6 +8011,9 @@ msgstr "limite paralelo de cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Esta fonte será usada para determinados idiomas."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Para ativar as sombras é necessário usar o controlador OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Ativar/Desativar câmera cinemática"
 
@@ -7925,6 +8037,15 @@ msgstr "limite paralelo de cURL"
 #~ msgid "Waving water"
 #~ msgstr "Balançar das Ondas"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Se as fontes FreeType são usadas, requer que suporte FreeType tenha sido "
+#~ "compilado.\n"
+#~ "Se desativado, fontes de bitmap e de vetores XML são usadas em vez disso."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Se dungeons ocasionalmente se projetam do terreno."
 
@@ -7941,5 +8062,9 @@ msgstr "limite paralelo de cURL"
 #~ msgid "Yes"
 #~ msgstr "Sim"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Você morreu"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index edb8b8324ead5a3516c1c12cfa2aa84c92447c3a..58a9805231c5b97078fea8d7706d7a86d9f830f8 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Portuguese (Brazil) (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-02-23 15:50+0000\n"
-"Last-Translator: Victor Barcelos Lacerda <victornuti.1@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-12-11 04:51+0000\n"
+"Last-Translator: Gabriel Cardoso <g.cardoso@mailfence.com>\n"
 "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
 "minetest/minetest/pt_BR/>\n"
 "Language: pt_BR\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.5\n"
+"X-Generator: Weblate 4.10-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Tamanho máximo da fila do chat"
+msgstr "Limpe a fila de espera do chat"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Comandos de Chat"
+msgstr "Comando vazio."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Sair para o menu"
+msgstr "Sair para o menu principal"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Comando local"
+msgstr "Comando inválido: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Comando emitido: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Um jogador"
+msgstr "Liste os jogadores online"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Um jogador"
+msgstr "Jogadores online: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "A fila de espera do chat agora está vazia."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Este comando está desabilitado pelo servidor."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,41 +58,40 @@ msgstr "Reviver"
 msgid "You died"
 msgstr "Você morreu"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Você morreu"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Comando local"
+msgstr "Comandos disponíveis:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Comando local"
+msgstr "Comandos disponíveis: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Comando não disponível: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Obtenha ajuda para comandos"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Use '.help <cmd>' para conseguir mais informação, ou '.help all' para listar "
+"tudo."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all| <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
-msgstr "OK"
+msgstr "Ok"
+
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<Comando não disponível>"
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
@@ -134,7 +127,7 @@ msgstr "O servidor suporta versões de protocolo entre $1 e $2. "
 
 #: builtin/mainmenu/common.lua
 msgid "We only support protocol version $1."
-msgstr "Suportamos apenas o protocolo de versão $1."
+msgstr "Nós só suportamos a versão do protocolo $1."
 
 #: builtin/mainmenu/common.lua
 msgid "We support protocol versions between version $1 and $2."
@@ -303,6 +296,10 @@ msgstr "Instalar $1"
 msgid "Install missing dependencies"
 msgstr "Instalar dependências ausentes"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Instalação: Tipo de arquivo não suportado ou corrompido"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -632,7 +629,7 @@ msgid "Offset"
 msgstr "Deslocamento"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Persistência"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -744,14 +741,6 @@ msgstr ""
 "Instalação de mod: não foi possível encontrar o nome da pasta adequado para "
 "o modpack $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Instalação: Tipo de arquivo \"$1\" não suportado ou corrompido"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instalação: arquivo: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Incapaz de encontrar um mod ou modpack válido"
@@ -777,9 +766,8 @@ msgid "Loading..."
 msgstr "Carregando..."
 
 #: builtin/mainmenu/serverlistmgr.lua
-#, fuzzy
 msgid "Public server list is disabled"
-msgstr "Scripting de cliente está desabilitado"
+msgstr "A lista de servidores públicos está desabilitada"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
@@ -789,16 +777,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Sobre"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Colaboradores Ativos"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Alcance para envio de objetos ativos"
+msgstr "Renderizador ativo:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -933,9 +920,8 @@ msgid "Start Game"
 msgstr "Iniciar Jogo"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Endereço: "
+msgstr "Endereço"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -951,22 +937,20 @@ msgstr "Modo criativo"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Dano"
+msgstr "Dano / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Rem. Favorito"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favorito"
+msgstr "Favoritos"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Servidores incompatíveis"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -977,16 +961,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Anunciar Servidor"
+msgstr "Servidores Públicos"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Atualizar"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Descrição do servidor"
 
@@ -1031,13 +1013,12 @@ msgid "Connected Glass"
 msgstr "Vidro conectado"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Fonte de sombra"
+msgstr "Sombras dinâmicas"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Sombras dinâmicas: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1045,15 +1026,15 @@ msgstr "Folhas com transparência"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Baixo"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Médio"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1127,10 +1108,6 @@ msgstr "Iluminação suave"
 msgid "Texturing:"
 msgstr "Texturização:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Para habilitar os sombreadores é necessário usar o driver OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tone mapping"
@@ -1145,11 +1122,11 @@ msgstr "Filtragem tri-linear"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Muito Alto"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Muito Baixo"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1163,7 +1140,7 @@ msgstr "Líquidos com ondas"
 msgid "Waving Plants"
 msgstr "Plantas balançam"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Erro de conexão (tempo excedido)."
 
@@ -1192,8 +1169,8 @@ msgid "Connection error (timed out?)"
 msgstr "Erro de conexão (tempo excedido?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Não foi possível localizar ou carregar jogo \""
+msgid "Could not find or load game"
+msgstr "Não foi possível localizar ou carregar jogo "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1236,14 +1213,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Endereço: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Modo Criativo: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "-Dano: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Modo: "
@@ -1265,6 +1234,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "Nome do servidor: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Ocorreu um erro:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Acesso negado. Razão:%s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Avanço automático para frente desabilitado"
@@ -1273,6 +1251,22 @@ msgstr "Avanço automático para frente desabilitado"
 msgid "Automatic forward enabled"
 msgstr "Avanço automático para frente habilitado"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Limites de bloco ocultos"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Limites de bloco mostrados para todos os blocos"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Limites de bloco mostrados para o bloco atual"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Limites de bloco mostrados para blocos próximos"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Atualização da camera desabilitada"
@@ -1281,6 +1275,10 @@ msgstr "Atualização da camera desabilitada"
 msgid "Camera update enabled"
 msgstr "Atualização da camera habilitada"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Alterar a senha"
@@ -1293,6 +1291,10 @@ msgstr "Modo cinemático desabilitado"
 msgid "Cinematic mode enabled"
 msgstr "Modo cinemático habilitado"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Cliente desconectado"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Scripting de cliente está desabilitado"
@@ -1301,6 +1303,10 @@ msgstr "Scripting de cliente está desabilitado"
 msgid "Connecting to server..."
 msgstr "Conectando ao servidor..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "A conexão falhou por motivo desconhecido"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Continuar"
@@ -1338,6 +1344,11 @@ msgstr ""
 "- Roda do mouse: selecionar item\n"
 "- %s: bate-papo\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Não foi possível resolver o endereço:%s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Criando o cliente..."
@@ -1467,9 +1478,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Minipapa atualmente desabilitado por jogo ou mod"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Um jogador"
+msgstr "Multi-jogador"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1543,6 +1553,21 @@ msgstr "Sistema de som não é suportado nesta versão"
 msgid "Sound unmuted"
 msgstr "Som desmutado"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "O servidor provavelmente está executando uma versão diferente de%s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Não foi possível conectar a%s porque o IPv6 está desativado"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Incapaz de escutar em%s porque IPv6 está desabilitado"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1877,6 +1902,14 @@ msgstr "Minimapa em modo de superfície, Zoom %dx"
 msgid "Minimap in texture mode"
 msgstr "Minimapa em modo de textura"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Falha ao abrir página da web"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Abrindo página da web"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "As senhas não correspondem!"
@@ -1906,7 +1939,6 @@ msgid "Proceed"
 msgstr "Continuar"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
 msgstr "\"Especial\" = descer"
 
@@ -1920,7 +1952,7 @@ msgstr "Pulo automático"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Especial"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1928,7 +1960,7 @@ msgstr "Voltar"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Limites de bloco"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2081,8 +2113,9 @@ msgid "Muted"
 msgstr "Mutado"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Volume do som: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Volume do som: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2107,15 +2140,14 @@ msgstr ""
 "toque."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Use joystick virtual para ativar botão \"aux\".\n"
-"Se habilitado, o joystick virtual vai também clicar no botão \"aux\" quando "
-"estiver fora do circulo principal."
+"(Android) Use joystick virtual para ativar botão \"especial\".\n"
+"Se habilitado, o joystick virtual vai também clicar no botão \"especial\" "
+"quando estiver fora do circulo principal."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2346,6 +2378,12 @@ msgstr ""
 "Ajustar configuração de dpi (profundidade de cor) para sua tela (apenas para "
 "quem não usa X11/Android) Ex para telas 4K."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Ajuste a densidade de exibição detectada, usada para dimensionar os "
+"elementos da IU."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2484,14 +2522,12 @@ msgid "Autoscaling mode"
 msgstr "Modo de alto escalamento"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Tecla para Pular"
+msgstr "Tecla especial"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Tecla especial pra escalar/descer"
+msgstr "Tecla Aux1 pra escalar/descer"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2643,9 +2679,12 @@ msgstr ""
 "Onde 0.0 é o nível mínimo de luz, 1.0 é o nível máximo de luz."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Limite da mensagem de expulsão"
+msgstr "Limite de mensagem de tempo de comando de bate-papo"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Comandos de Chat"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2680,8 +2719,8 @@ msgid "Chat toggle key"
 msgstr "Tecla comutadora de chat"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Comandos de Chat"
+msgid "Chat weblinks"
+msgstr "Links de bate-papo"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2699,6 +2738,14 @@ msgstr "Tecla para modo cinematográfico"
 msgid "Clean transparent textures"
 msgstr "Limpe as texturas transparentes"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Links da web clicáveis (clique do meio ou Ctrl + botão esquerdo) ativados na "
+"saída do console de bate-papo."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Cliente"
@@ -2744,9 +2791,8 @@ msgid "Colored fog"
 msgstr "Névoa colorida"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Névoa colorida"
+msgstr "Sombra colorida"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2761,10 +2807,11 @@ msgstr ""
 "Lista de flags separadas por vírgula para esconder no repositório de "
 "conteúdos.\n"
 "\"não livre\" pode ser usada para esconder pacotes que não se qualificam "
-"como software livre, como definido pela fundação do software livre.\n"
+"como software livre,\n"
+"como definido pela fundação do software livre.\n"
 "Você também pode especificar classificação de conteúdo.\n"
-"Essas flags são independentes das versões do minetest, veja a lista completa "
-"em https://content.minetest.net/help/content_flags/"
+"Essas flags são independentes das versões do minetest,\n"
+"veja a lista completa em https://content.minetest.net/help/content_flags/"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2788,6 +2835,34 @@ msgstr ""
 msgid "Command key"
 msgstr "Tecla de Comando"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Nível de compressão ZLib a ser usada ao salvar mapblocks no disco.\n"
+"-1 - Nível de compressão padrão do Zlib\n"
+"0 - Nenhuma compressão; o mais rápido\n"
+"9 - Melhor compressão; o mais devagar\n"
+"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
+"normal)"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Nível de compressão ZLib a ser usada ao mandar mapblocks para o cliente.\n"
+"-1 - Nível de compressão padrão do Zlib\n"
+"0 - Nenhuma compressão; o mais rápido\n"
+"9 - Melhor compressão; o mais devagar\n"
+"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
+"normal)"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Vidro conectado"
@@ -2888,10 +2963,10 @@ msgstr "Alpha do cursor"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
-"Alpha do cursor (quanto ele é opaco, níveis entre 0 e 255).\n"
-"Também controla a cor da cruz do objeto"
+"Alpha do cursor (quanto ele é opaco, níveis entre 0 e 255).\n"
+"Também controla a cor da cruz do objeto."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2971,10 +3046,13 @@ msgstr "Tamanho padrão de stack"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Define a qualidade de filtragem de sombreamento\n"
+"Isso simula um efeito de sombras suaves aplicando um PCF ou um Poisson disk\n"
+"mas também usa mais recursos."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3038,9 +3116,9 @@ msgid ""
 "Delay between mesh updates on the client in ms. Increasing this will slow\n"
 "down the rate of mesh updates, thus reducing jitter on slower clients."
 msgstr ""
-"Tempo entre atualizações das malhas 3D no cliente em milissegundos. Aumentar "
-"isso vai retardar a taxa de atualização das malhas, sendo assim, reduzindo "
-"travamentos em clientes lentos."
+"Tempo entre atualizações das malhas 3D no cliente em milissegundos.\n"
+"Aumentar isso vai retardar a taxa de atualização das malhas, sendo assim, "
+"reduzindo travamentos em clientes lentos."
 
 #: src/settings_translation_file.cpp
 msgid "Delay in sending blocks after building"
@@ -3102,6 +3180,10 @@ msgstr "Habilitar Anti-Hack"
 msgid "Disallow empty passwords"
 msgstr "Não permitir logar sem senha"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Domínio do servidor, para ser mostrado na lista de servidores."
@@ -3152,18 +3234,30 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Ativa filtragem de Poisson disk.\n"
+"Quando em true usa o Poisson disk para fazer \"sombras suaves\". Caso "
+"contrário, usa filtragem PCF."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Ativa sombras coloridas.\n"
+"Quando em true, nodes translúcidos podem projetar sombras coloridas. Requer "
+"o uso de muitos recursos."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
 msgstr "Habilitar janela de console"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable creative mode for all players"
-msgstr "Habilitar modo criativo para mundos novos."
+msgstr "Habilitar modo criativo para todos os jogadores."
 
 #: src/settings_translation_file.cpp
 msgid "Enable joysticks"
@@ -3181,13 +3275,6 @@ msgstr "Habilitar Mod Security (Segurança nos mods)"
 msgid "Enable players getting damage and dying."
 msgstr "Permitir que os jogadores possam sofrer dano e morrer."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Habilitar entrada de comandos aleatórios (apenas usado para testes)."
@@ -3223,8 +3310,8 @@ msgstr ""
 "Habilitar recurso de não permitir que jogadores usando versões antigas do "
 "cliente possam se conectar.\n"
 "Essas versões são compatíveis no sentido de não travar quando conectam a "
-"servidores com versões mais atuais, porém eles podem não suportar todos os "
-"recursos que você está esperando."
+"servidores com versões mais atuais,\n"
+"porém eles podem não suportar todos os recursos que você está esperando."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3302,6 +3389,12 @@ msgstr ""
 "e os controles de som dentro do jogo se tornarão não funcionais.\n"
 "Mudar esta configuração requer uma reinicialização."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Intervalo de exibição dos dados das analizes do motor"
@@ -3365,12 +3458,11 @@ msgid "Fast movement"
 msgstr "Modo rápido"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Movimento rápido (através da tecla \"especial\").\n"
+"Movimento rápido (através da tecla \"Aux1\").\n"
 "Isso requer o privilegio \"fast\" no servidor."
 
 #: src/settings_translation_file.cpp
@@ -3388,7 +3480,8 @@ msgid ""
 "Multiplayer Tab."
 msgstr ""
 "Arquivo na pasta client/serverlist/ que contém seus servidores favoritos, "
-"que são mostrados na aba Multijogador."
+"que são mostrados na\n"
+"aba Multijogador."
 
 #: src/settings_translation_file.cpp
 msgid "Filler depth"
@@ -3403,7 +3496,6 @@ msgid "Filmic tone mapping"
 msgstr "Filmic Tone Mapping"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3413,7 +3505,8 @@ msgstr ""
 "Texturas filtradas podem misturar valores RGB com os vizinhos totalmente \n"
 "transparentes, o qual otimizadores PNG geralmente descartam, por vezes \n"
 "resultando em uma linha escura em texturas transparentes.\n"
-"Aplicar esse filtro para limpar isso no tempo de carregamento da textura."
+"Aplique esse filtro para limpar isso no momento de carregamento da textura.\n"
+"Esse filtro será ativo automaticamente ao ativar \"mipmapping\"."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3505,11 +3598,17 @@ msgid "Font size"
 msgstr "Tamanho da fonte"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Tamanho da fonte padrão em pontos (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Tamanho da fonte de largura fixa em pontos (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3521,6 +3620,17 @@ msgstr ""
 "pontos (pt).\n"
 "O valor 0 irá utilizar o tamanho padrão de fonte."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3584,10 +3694,6 @@ msgstr "Tipo fractal"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Fração da distância visível em que a névoa começa a aparecer"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Fontes Freetype"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3613,7 +3719,8 @@ msgid ""
 msgstr ""
 "De quão longe clientes sabem sobre objetos declarados em mapblocks (16 "
 "nós).\n"
-" Configurando isto maior do que o alcançe de bloco ativo vai fazer com que o "
+"\n"
+"Configurando isto maior do que o alcançe de bloco ativo vai fazer com que o "
 "sevidor mantenha objetos ativos na distancia que o jogador está olhando."
 "(Isso pode evitar que mobs desapareçam da visão de repente)"
 
@@ -3645,10 +3752,10 @@ msgstr "Chamadas de retorno Globais"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Atributos de geração de mapa globais.\n"
-"No gerador de mapa v6 a flag 'decorations' controla todas as decorações "
+"No gerador de mapa v6 a flag 'decorations' controla todas as decorações, "
 "exceto árvores\n"
 "e gramas da selva, em todos os outros geradores de mapa essa flag controla "
 "todas as decorações."
@@ -3733,10 +3840,11 @@ msgid "Heat noise"
 msgstr "Ruído nas cavernas #1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Altura da janela inicial."
+msgstr ""
+"Componente de altura do tamanho da janela inicial. Ignorado em modo de tela "
+"cheia."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3989,13 +4097,13 @@ msgstr ""
 "para não gastar a potência da CPU desnecessariamente."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Se estiver desabilitado, a tecla \"especial será usada para voar rápido se "
-"modo voo e rápido estiverem habilitados."
+"Se estiver desabilitado, a tecla \"especial\" será usada para voar rápido se "
+"modo voo e rápido estiverem\n"
+"habilitados."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4006,9 +4114,10 @@ msgid ""
 "so that the utility of noclip mode is reduced."
 msgstr ""
 "Se habilitado, o servidor executará a seleção de oclusão de bloco de mapa "
-"com base na posição do olho do jogador. Isso pode reduzir o número de blocos "
-"enviados ao cliente de 50 a 80%. O cliente não será mais mais invisível, de "
-"modo que a utilidade do modo \"noclip\" (modo intangível) será reduzida."
+"com base\n"
+"na posição do olho do jogador. Isso pode reduzir o número de blocos\n"
+"enviados ao cliente de 50 a 80%. O cliente não receberá mais invisível\n"
+"para que a utilidade do modo noclip é reduzida."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4021,14 +4130,13 @@ msgstr ""
 "Isso requer o privilégio \"noclip\" no servidor."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Se habilitado, a tecla \"especial\" em vez de \"esgueirar\" servirá para "
-"usada descer."
+"Se habilitado, a tecla \"especial\" em vez de \"esgueirar\" servirá para\n"
+"descer."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4079,13 +4187,17 @@ msgid ""
 "to this distance from the player to the node."
 msgstr ""
 "Se a restrição de CSM para alcançe de nós está habilitado, chamadas get_node "
-"são limitadas a está distancia do player até o nó."
+"são limitadas\n"
+"a esta distancia do player até o node."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Se a execução de um comando de chat demorar mais do que o tempo especificado "
+"em\n"
+"segundos, adicione a informação do tempo na mensagem-comando"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4148,7 +4260,8 @@ msgstr ""
 "Isto é necessário apenas por contribuidores core/builtin"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Monitoração de comandos de chat quando registrados."
 
 #: src/settings_translation_file.cpp
@@ -4229,8 +4342,8 @@ msgid ""
 "At iterations = 20 this mapgen has a similar load to mapgen V7."
 msgstr ""
 "Iterações da função recursiva.\n"
-"Aumentando isso aumenta a quantidade de detalhes, mas também aumenta o tempo "
-"de processamento.\n"
+"Aumentando isso aumenta a quantidade de detalhes, mas também\n"
+"aumenta o tempo de processamento.\n"
 "Com iterações = 20, esse gerador de mapa tem um tempo de carregamento "
 "similar ao gerador V7."
 
@@ -4243,7 +4356,7 @@ msgid "Joystick button repetition interval"
 msgstr "Intervalo de repetição do botão do Joystick"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "\"Zona morta\" do joystick"
 
 #: src/settings_translation_file.cpp
@@ -4263,7 +4376,8 @@ msgid ""
 "Range roughly -2 to 2."
 msgstr ""
 "Apenas para a configuração de Julia.\n"
-"Componente W da constante hipercomplexa determinando o formato do fractal.\n"
+"Componente W da constante hipercomplexa.\n"
+"Altera o formato do fractal.\n"
 "Não tem nenhum efeito em fractais 3D.\n"
 "varia aproximadamente entre -2 e 2."
 
@@ -4288,6 +4402,7 @@ msgid ""
 msgstr ""
 "Apenas para configuração de Julia.\n"
 "Componente Y da constante hipercomplexa.\n"
+"Altera o formato do fractal.\n"
 "Varia aproximadamente entre -2 e 2."
 
 #: src/settings_translation_file.cpp
@@ -5107,7 +5222,8 @@ msgid ""
 "network."
 msgstr ""
 "Comprimento do tick do servidor e o intervalo no qual os objetos são "
-"geralmente atualizados em rede."
+"geralmente atualizados em\n"
+"rede."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5179,9 +5295,9 @@ msgid ""
 "Only mapchunks completely within the mapgen limit are generated.\n"
 "Value is stored per-world."
 msgstr ""
-"Limite de geração de mapas, em nós, em todas as 6 direções de (0, 0, 0). "
-"Apenas áreas completas de mapa dentro do limite do mapgen são gerados. O "
-"valor é armazenado por mundo."
+"Limite de geração de mapas, em nós, em todas as 6 direções de (0, 0, 0).\n"
+"Apenas áreas completas de mapa dentro do limite do mapgen são gerados.\n"
+"valor é armazenado por mundo."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5314,7 +5430,8 @@ msgstr ""
 "'altitude_chill':Reduz o calor com a altitude.\n"
 "'humid_rivers':Aumenta a umidade em volta dos rios.\n"
 "'profundidade_variada_rios': Se habilitado, baixa umidade e alto calor faz "
-"com que rios se tornem mais rasos e eventualmente sumam.\n"
+"com que rios\n"
+"se tornem mais rasos e eventualmente sumam.\n"
 "'altitude_dry': Reduz a umidade com a altitude."
 
 #: src/settings_translation_file.cpp
@@ -5356,8 +5473,8 @@ msgstr "Intervalo de salvamento de mapa"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
-msgstr "Período de atualização dos Líquidos"
+msgid "Map shadows update frames"
+msgstr "Tempo de atualização do mapa"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5472,7 +5589,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Distância máxima para renderizar sombras"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5560,9 +5677,9 @@ msgid ""
 "client number."
 msgstr ""
 "Número máximo de pacotes enviados por etapa de envio, se você tem uma "
-"conexão lenta \n"
-"tente reduzir isso, mas não reduza a um número abaixo do dobro do número de "
-"cliente alvo."
+"conexão lenta\n"
+"tente reduzir isso, mas não reduza a um número abaixo do dobro do\n"
+"número de cliente alvo."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of players that can be connected simultaneously."
@@ -5605,19 +5722,19 @@ msgstr ""
 "0 para desabilitar a fila e -1 para a tornar ilimitada."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Tempo máximo em ms para download de arquivo (por exemplo, um arquivo ZIP de "
-"um modificador) pode tomar."
+"Tempo máximo em ms para download de arquivo (por exemplo, um mod) pode tomar."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Tempo máximo que um pedido interativo (ex: busca de lista de servidores) "
+"pode levar, em milissegundos."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5680,7 +5797,7 @@ msgid "Mod channels"
 msgstr "Canais de mod"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr "Modifica o tamanho dos elementos do hudbar."
 
 #: src/settings_translation_file.cpp
@@ -5691,6 +5808,11 @@ msgstr "Caminho de fonte monoespaçada"
 msgid "Monospace font size"
 msgstr "Tamanho da fonte monoespaçada"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Tamanho da fonte monoespaçada"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Parâmetros ruido da altura de montagem do gerador de mundo v7"
@@ -5840,13 +5962,13 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Número de blocos extras que pode ser carregados por /clearobjects ao mesmo "
 "tempo.\n"
-"Esta é uma troca entre sobrecarga de transação do sqlite e consumo de "
-"memória (4096 = 100 MB, como uma regra de ouro)."
+"Esta é uma troca entre sobrecarga de transação do sqlite e\n"
+"consumo de memória (4096 = 100 MB, como uma regra de ouro)."
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
@@ -5868,13 +5990,17 @@ msgid ""
 "open."
 msgstr ""
 "Abre o menu de pausa quando o foco da janela é perdido.Não pausa se um "
-"formspec está aberto."
+"formspec está\n"
+"aberto."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Substituição opcional da cor do link do bate-papo."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5908,10 +6034,9 @@ msgstr ""
 "primeiro daqui."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Caminho para a fonte padrão.\n"
@@ -5921,10 +6046,9 @@ msgstr ""
 "A fonte alternativa será usada se não for possível carregar essa."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Caminho para a fonte monoespaçada.\n"
@@ -5987,9 +6111,8 @@ msgid "Player versus player"
 msgstr "Jogador contra jogador"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Filtragem bi-linear"
+msgstr "Filtragem de Poisson"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6018,8 +6141,8 @@ msgid ""
 "Print the engine's profiling data in regular intervals (in seconds).\n"
 "0 = disable. Useful for developers."
 msgstr ""
-"Intervalo de impressão de dados do analisador (em segundos). 0 = "
-"desabilitado. Útil para desenvolvedores."
+"Intervalo de impressão de dados do analisador (em segundos).\n"
+"0 = desabilitado. Útil para desenvolvedores."
 
 #: src/settings_translation_file.cpp
 msgid "Privileges that players with basic_privs can grant"
@@ -6044,9 +6167,9 @@ msgstr "Endereço do Prometheus"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Endereço do Prometheus\n"
 "Se o minetest for compilado com a opção ENABLE_PROMETHEUS ativa,\n"
@@ -6126,7 +6249,8 @@ msgid ""
 msgstr ""
 "Restringe o acesso de certas funções a nível de cliente em servidores.\n"
 "Combine os byflags abaixo par restringir recursos de nível de cliente, ou "
-"coloque 0 para nenhuma restrição:\n"
+"coloque 0\n"
+"para nenhuma restrição:\n"
 "LOAD_CLIENT_MODS: 1 (desabilita o carregamento de mods de cliente)\n"
 "CHAT_MESSAGES: 2 (desabilita a chamada send_chat_message no lado do "
 "cliente)\n"
@@ -6391,37 +6515,38 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Defina a força da sombra.\n"
+"Valores mais baixo significam sombras mais brandas, valores mais altos "
+"significam sombras mais fortes."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Defina o tamanho do raio de sombras suaves.\n"
+"Valores mais baixos significam sombras mais nítidas e valores altos sombras "
+"suaves.\n"
+"Valor mínimo 1.0 e valor máximo 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Defina a inclinação da órbita do Sol/Lua em graus\n"
+"Valor 0 significa sem inclinação/ órbita vertical.\n"
+"Valor mínimo de 0.0 e máximo de 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Definido como true habilita o balanço das folhas.\n"
-"Requer que os sombreadores estejam ativados."
+"Defina para true para ativar o Mapeamento de Sombras.\n"
+"Requer sombreadores para ser ativado."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6453,6 +6578,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Define a qualidade da textura das sombras para 32 bits.\n"
+"Quando false, a textura de 16 bits será usada\n"
+"Isso pode fazer com que muito mais coisas aparecam nas sombras."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6466,26 +6594,25 @@ msgid ""
 "This only works with the OpenGL video backend."
 msgstr ""
 "Sombreadores permitem efeitos visuais avançados e podem aumentar a "
-"performance em algumas placas de vídeo.\n"
+"performance em algumas\n"
+"placas de vídeo.\n"
 "Só funcionam com o modo de vídeo OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Qualidade da Captura de tela;"
+msgstr "Qualidade do filtro de sombras"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Distância do mapa de sombras em nodes para renderizar sombras"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Textura do mapa de sombras em 32 bits"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Tamanho mínimo da textura"
+msgstr "Tamanho da textura do mapa de sombras"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6497,7 +6624,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Força da sombra"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6520,9 +6647,8 @@ msgstr ""
 "É necessário reiniciar após alterar isso."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Show nametag backgrounds by default"
-msgstr "Fonte em negrito por padrão"
+msgid "Show name tag backgrounds by default"
+msgstr "Mostrar plano de fundo da nametag por padrão"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6555,7 +6681,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Inclinação Da Órbita Do Céu"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6617,9 +6743,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Velocidade ao esgueirar-se, em nós (blocos) por segundo."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Fonte alpha de sombra"
+msgstr "Raio das sombras suaves"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6648,6 +6773,14 @@ msgstr ""
 "Note que mods e games talvez definam explicitamente um tamanho para certos "
 "(ou todos) os itens."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6785,8 +6918,11 @@ msgstr "Diretorio da textura"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Tamanho da textura em que o mapa de sombras será renderizado em.\n"
+"Deve ser um múltiplo de dois.\n"
+"Números maiores criam sombras melhores mas também esvazia a conta do banco."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6810,7 +6946,7 @@ msgid "The URL for the content repository"
 msgstr "A url para o repositório de conteúdo"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "A zona morta do joystick"
 
 #: src/settings_translation_file.cpp
@@ -6886,7 +7022,6 @@ msgstr ""
 "Isso deve ser configurado junto com active_object_send_range_blocks."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6895,7 +7030,7 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"O back-end de renderização para Irrlicht.\n"
+"O back-end de renderização.\n"
 "É necessário reiniciar após alterar isso.\n"
 "Nota: No Android, use OGLES1 se não tiver certeza! O aplicativo pode falhar "
 "ao iniciar de outra forma.\n"
@@ -6903,9 +7038,10 @@ msgstr ""
 "Shaders são suportados por OpenGL (somente desktop) e OGLES2 (experimental)"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "A sensibilidade dos eixos do joystick para movimentar o frustum de exibição "
 "no jogo."
@@ -7028,6 +7164,10 @@ msgstr "Atraso de dica de ferramenta"
 msgid "Touch screen threshold"
 msgstr "Limiar a tela de toque"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Ruido de árvores"
@@ -7106,8 +7246,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Usar filtragem bilinear ao dimensionamento de texturas."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7241,9 +7382,8 @@ msgid "Viewing range"
 msgstr "Intervalo de visualização"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Joystick virtual ativa botão auxiliar"
+msgstr "Joystick virtual ativa botão especial"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7319,6 +7459,11 @@ msgstr "Comprimento de balanço da água"
 msgid "Waving plants"
 msgstr "Balanço das plantas"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Cor da caixa de seleção"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7348,7 +7493,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7367,20 +7512,13 @@ msgstr ""
 "texturas."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Se as fontes FreeType são usadas, requer que suporte FreeType tenha sido "
-"compilado.\n"
-"Se desativado, fontes de bitmap e de vetores XML são usadas em seu lugar."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
+"Se os planos de fundo das nametags devem ser mostradas por padrão.\n"
+"Mods ainda poderão definir um plano de fundo."
 
 #: src/settings_translation_file.cpp
 msgid "Whether node texture animations should be desynchronized per mapblock."
@@ -7434,9 +7572,9 @@ msgstr ""
 "como teclar F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Largura da janela inicial."
+msgstr ""
+"Componente de tamanho da janela inicial. Ignorado em modo de tela cheia."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7539,36 +7677,6 @@ msgstr "Nível Y de terreno inferior e solo oceânico."
 msgid "Y-level of seabed."
 msgstr "Nível Y do fundo do mar."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Nível de compressão ZLib a ser usada ao salvar mapblocks no disco.\n"
-"-1 - Nível de compressão padrão do Zlib\n"
-"0 - Nenhuma compressão; o mais rápido\n"
-"9 - Melhor compressão; o mais devagar\n"
-"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
-"normal)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Nível de compressão ZLib a ser usada ao mandar mapblocks para o cliente.\n"
-"-1 - Nível de compressão padrão do Zlib\n"
-"0 - Nenhuma compressão; o mais rápido\n"
-"9 - Melhor compressão; o mais devagar\n"
-"(níveis 1-3 usam método \"rápido\" do Zlib, enquanto que 4-9 usam método "
-"normal)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Tempo limite de download de arquivo via cURL"
@@ -7582,6 +7690,12 @@ msgstr "Tempo limite de cURL"
 msgid "cURL parallel limit"
 msgstr "limite paralelo de cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Modo Criativo: "
+
+#~ msgid "- Damage: "
+#~ msgstr "-Dano: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7755,6 +7869,9 @@ msgstr "limite paralelo de cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Tamanho da fonte reserva em pontos (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Fontes Freetype"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Tela cheia BPP"
 
@@ -7773,6 +7890,9 @@ msgstr "limite paralelo de cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "Suporte a IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instalação: arquivo: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Profundidade da lava"
 
@@ -7876,6 +7996,17 @@ msgstr "limite paralelo de cURL"
 #~ msgid "Select Package File:"
 #~ msgstr "Selecionar o arquivo do pacote:"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "Defina o tempo de atualização das sombras.\n"
+#~ "Valores mais baixos significam que sombras e mapa atualizam mais rápido, "
+#~ "mas consume mais recursos.\n"
+#~ "Valor mínimo 0.001 segundos e valor máximo 0.2 segundos"
+
 #~ msgid "Shadow limit"
 #~ msgstr "Limite de mapblock"
 
@@ -7904,6 +8035,9 @@ msgstr "limite paralelo de cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Esta fonte será usada para determinados idiomas."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Para habilitar os sombreadores é necessário usar o driver OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Alternar modo de câmera cinemática"
 
@@ -7927,6 +8061,15 @@ msgstr "limite paralelo de cURL"
 #~ msgid "Waving water"
 #~ msgstr "Balanço da água"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Se as fontes FreeType são usadas, requer que suporte FreeType tenha sido "
+#~ "compilado.\n"
+#~ "Se desativado, fontes de bitmap e de vetores XML são usadas em seu lugar."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Se dungeons ocasionalmente se projetam do terreno."
 
@@ -7943,5 +8086,8 @@ msgstr "limite paralelo de cURL"
 #~ msgid "Yes"
 #~ msgstr "Sim"
 
+#~ msgid "You died."
+#~ msgstr "Você morreu."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 31c7fa9c92b80fcf37b8d657f4c4644bbef75fb9..484fe4d4b1ce5a3f59404c8aefd085c23ac46c4a 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Romanian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-04-28 01:32+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-07-25 23:36+0000\n"
 "Last-Translator: Nicolae Crefelean <kneekoo@yahoo.com>\n"
 "Language-Team: Romanian <https://hosted.weblate.org/projects/minetest/"
 "minetest/ro/>\n"
@@ -13,48 +13,43 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
 "20)) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Golește coada mesajelor de chat"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Comenzi de chat"
+msgstr "Comenzi de chat."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Ieși în Meniu"
+msgstr "Ieși în meniul principal"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Comandă locală"
+msgstr "Comandă greșită: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Comanda dată: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Jucător singur"
+msgstr "Arată jucătorii conectați"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Jucător singur"
+msgstr "Jucători conectați: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Coada mesajelor de chat a fost golită."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Această comandă este dezactivată de server."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +59,42 @@ msgstr "Reînviere"
 msgid "You died"
 msgstr "Ai murit"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Ai murit"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Comandă locală"
+msgstr "Comenzi disponibile:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Comandă locală"
+msgstr "Comenzi disponibile: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Comandă indisponibilă: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Obține ajutor pentru comenzi"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Folosește „.help <cmd>” pentru detalii sau „.help all” pentru informații "
+"complete."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "Comandă indisponibilă: "
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "A apărut o eroare într-un script Lua:"
@@ -235,7 +230,7 @@ msgstr "Dependențele $1 și $2 vor fi instalate."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1, de $2"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
@@ -302,6 +297,11 @@ msgstr "Instalează $1"
 msgid "Install missing dependencies"
 msgstr "Instalează dependințele opționale"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Instalare: tipul de fișier neacceptat „$ 1” sau arhiva ruptă"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -349,11 +349,11 @@ msgstr "Actualizare"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
-msgstr ""
+msgstr "Actualizează tot [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "Vezi detalii într-un navigator web"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
@@ -632,7 +632,8 @@ msgid "Offset"
 msgstr "Decalaj"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Persistență"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -744,14 +745,6 @@ msgstr ""
 "Instalare Mod: nu se poate găsi nume de folder potrivit pentru pachetul de "
 "moduri $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Instalare: tipul de fișier neacceptat „$ 1” sau arhiva ruptă"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Instalare: fișier: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Nu se poate găsi un mod sau un pachet de moduri valid"
@@ -788,16 +781,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Despre"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Contribuitori activi"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Interval de trimitere obiect e activ"
+msgstr "Tipul curent de randare:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -812,6 +804,8 @@ msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"Deschide într-un manager de fișiere directorul care conține lumile,\n"
+"jocurile, modificările și texturile furnizate de utilizator."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
@@ -891,7 +885,7 @@ msgstr "Instalarea jocurilor din ContentDB"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "Nume"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
@@ -930,9 +924,8 @@ msgid "Start Game"
 msgstr "Începe Jocul"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adresa: "
+msgstr "Adresă"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -948,22 +941,20 @@ msgstr "Modul Creativ"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Daune"
+msgstr "Daune / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Şterge Favorit"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favorit"
+msgstr "Favorite"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Servere incompatibile"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -974,16 +965,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Anunțare server"
+msgstr "Servere publice"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Actualizează"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Descrierea serverului"
 
@@ -1029,15 +1018,15 @@ msgstr "Sticlă conectată"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "Umbre dinamice"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Umbre dinamice: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
-msgstr "Frunze luxsoase"
+msgstr "Frunze detaliate"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
@@ -1123,10 +1112,6 @@ msgstr "Lumină fină"
 msgid "Texturing:"
 msgstr "Texturare:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Pentru a permite shadere OpenGL trebuie să fie folosite."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Mapare ton"
@@ -1159,7 +1144,7 @@ msgstr "Fluturarea lichidelor"
 msgid "Waving Plants"
 msgstr "Plante legănătoare"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Conexiunea a expirat."
 
@@ -1188,7 +1173,8 @@ msgid "Connection error (timed out?)"
 msgstr "Eroare de conexiune (timeout?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Nu se poate găsi sau încărca jocul \""
 
 #: src/client/clientlauncher.cpp
@@ -1231,14 +1217,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresa: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Modul creativ: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Daune: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Modul: "
@@ -1260,6 +1238,16 @@ msgstr "- Jucător vs jucător: "
 msgid "- Server Name: "
 msgstr "- Numele serverului: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "A apărut o eroare:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Redirecționare automată dezactivată"
@@ -1268,6 +1256,22 @@ msgstr "Redirecționare automată dezactivată"
 msgid "Automatic forward enabled"
 msgstr "Redirecționare automată activată"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Actualizarea camerei este dezactivată"
@@ -1276,6 +1280,10 @@ msgstr "Actualizarea camerei este dezactivată"
 msgid "Camera update enabled"
 msgstr "Actualizarea camerei este activată"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Schimbă Parola"
@@ -1288,6 +1296,11 @@ msgstr "Modul cinematografic este dezactivat"
 msgid "Cinematic mode enabled"
 msgstr "Modul cinematografic activat"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Modare la client"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Scripturile din partea clientului sunt dezactivate"
@@ -1296,6 +1309,10 @@ msgstr "Scripturile din partea clientului sunt dezactivate"
 msgid "Connecting to server..."
 msgstr "Se conectează la server..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Continuă"
@@ -1333,6 +1350,11 @@ msgstr ""
 "- Roata mausului: selectare obiect\n"
 "- %s: chat\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Se creează clientul..."
@@ -1538,6 +1560,21 @@ msgstr "Sistemul audio nu e suportat în această construcție"
 msgid "Sound unmuted"
 msgstr "Sunet activat"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1872,6 +1909,15 @@ msgstr "Mini hartă în modul de suprafață, Zoom %dx"
 msgid "Minimap in texture mode"
 msgstr "Mini hartă în modul de textură"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Nu s-a putut descărca $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Parolele nu se potrivesc!"
@@ -2075,7 +2121,8 @@ msgid "Muted"
 msgstr "Amuțit"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Volum sunet: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2336,6 +2383,10 @@ msgstr ""
 "Ajustați configurația dpi pe ecran (numai pentru x11/Android), de exemplu "
 "pentru ecrane 4k."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2637,6 +2688,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Pragul de lansare a mesajului de chat"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Comenzi de chat"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "Dimensiunea fontului din chat"
@@ -2670,8 +2726,9 @@ msgid "Chat toggle key"
 msgstr "Cheia de comutare a chatului"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Comenzi de chat"
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Chat afișat"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2689,6 +2746,12 @@ msgstr "Tasta modului cinematografic"
 msgid "Clean transparent textures"
 msgstr "Texturi transparente curate"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Client"
@@ -2775,6 +2838,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Tasta de comandă"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Sticla conectată"
@@ -2785,7 +2864,7 @@ msgstr "Se conectează la server media extern"
 
 #: src/settings_translation_file.cpp
 msgid "Connects glass if supported by node."
-msgstr ""
+msgstr "Unește sticla dacă nodul permite asta."
 
 #: src/settings_translation_file.cpp
 msgid "Console alpha"
@@ -2805,7 +2884,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Max Concurrent Downloads"
-msgstr ""
+msgstr "Maximul de descărcări simultane din ContentDB"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB URL"
@@ -2866,7 +2945,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2943,8 +3022,8 @@ msgstr "Dimensiunea implicită a stivei"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3062,6 +3141,10 @@ msgstr "Dezactivează anticheatul"
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3108,7 +3191,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3136,13 +3226,6 @@ msgstr "Activați securitatea modului"
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3227,6 +3310,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3411,11 +3500,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3424,6 +3517,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3483,10 +3587,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3535,7 +3635,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3967,7 +4067,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4051,7 +4151,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4880,7 +4980,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5173,7 +5273,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5184,6 +5284,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5305,7 +5409,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5329,11 +5433,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5356,17 +5462,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5470,9 +5572,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5765,26 +5867,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5876,7 +5970,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5982,6 +6076,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6092,7 +6194,7 @@ msgstr "Calea texturii"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6110,7 +6212,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6179,7 +6281,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6272,6 +6374,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr "Prag ecran tactil"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6342,7 +6448,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6525,6 +6631,10 @@ msgstr "Lungirea undei lichide"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6546,7 +6656,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6554,14 +6664,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6687,24 +6790,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6717,6 +6802,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Modul creativ: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Daune: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -6787,6 +6878,9 @@ msgstr ""
 #~ msgid "Generate Normal Maps"
 #~ msgstr "Generați Hărți Normale"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Instalare: fișier: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "Principal"
 
@@ -6839,6 +6933,9 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Începeți Jucător singur"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Pentru a permite shadere OpenGL trebuie să fie folosite."
+
 #, fuzzy
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Intră pe rapid"
@@ -6849,5 +6946,8 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "Da"
 
+#~ msgid "You died."
+#~ msgstr "Ai murit."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index cb00d28ef0485b90993d87fe895843045a90020f..916b15064194f71f58738c12a190eafc5dd3ed65 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Russian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-05-03 07:32+0000\n"
-"Last-Translator: Andrei Stepanov <adem4ik@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-29 21:28+0000\n"
+"Last-Translator: Nikita Epifanov <nikgreens@protonmail.com>\n"
 "Language-Team: Russian <https://hosted.weblate.org/projects/minetest/"
 "minetest/ru/>\n"
 "Language: ru\n"
@@ -13,49 +13,43 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Ð\9cакÑ\81ималÑ\8cнÑ\8bй Ñ\80азмеÑ\80 Ð¾Ñ\87еÑ\80еди Ð¸Ñ\81Ñ\85одÑ\8fÑ\89иÑ\85 Ñ\81ообÑ\89ений"
+msgstr "Ð\9eÑ\87иÑ\81Ñ\82иÑ\82Ñ\8c Ð¾Ñ\87еÑ\80едÑ\8c Ñ\87аÑ\82а"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Ð\9aомандÑ\8b Ð² Ñ\87аÑ\82е"
+msgstr "Ð\9fÑ\83Ñ\81Ñ\82аÑ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Выход в меню"
+msgstr "Ð\92Ñ\8bÑ\85од Ð² Ð³Ð»Ð°Ð²Ð½Ð¾Ðµ Ð¼ÐµÐ½Ñ\8e"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Ð\9bокалÑ\8cнаÑ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
+msgstr "Ð\9dевеÑ\80наÑ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Выданная команда: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Ð\9eдиноÑ\87наÑ\8f Ð¸Ð³Ñ\80а"
+msgstr "СпиÑ\81ок Ð¾Ð½Ð»Ð°Ð¹Ð½ Ð¸Ð³Ñ\80оков"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Ð\9eдиноÑ\87наÑ\8f Ð¸Ð³Ñ\80а"
+msgstr "Ð\9eнлайн Ð¸Ð³Ñ\80оки: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Очередь в чате теперь пуста."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Эта команда отключена сервером."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -65,42 +59,41 @@ msgstr "Возродиться"
 msgid "You died"
 msgstr "Вы умерли"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Вы умерли"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Ð\9bокалÑ\8cнаÑ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
+msgstr "Ð\94оÑ\81Ñ\82Ñ\83пнÑ\8bе ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Ð\9bокалÑ\8cнаÑ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
+msgstr "Ð\94оÑ\81Ñ\82Ñ\83пнÑ\8bе ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ\8b"
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Команда недоступна: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Получить справку по командам"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Используйте '.help <cmd>' для получения дополнительной информации, или '."
+"help all' для перечисления всего списка."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <команда>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "ОК"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<недоступно>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Произошла ошибка в скрипте Lua:"
@@ -303,6 +296,12 @@ msgstr "Установить $1"
 msgid "Install missing dependencies"
 msgstr "Установить недостающие зависимости"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"Установка мода: неподдерживаемый тип файла или повреждённый архив \"$1\""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -589,8 +588,8 @@ msgid ""
 "This modpack has an explicit name given in its modpack.conf which will "
 "override any renaming here."
 msgstr ""
-"ЭÑ\82оÑ\82 Ð¿Ð°ÐºÐµÑ\82 Ð¼Ð¾Ð´Ð¾Ð² Ð¸Ð¼ÐµÐµÑ\82 Ð¸Ð¼Ñ\8f, Ñ\8fвно Ñ\83казанное Ð² modpack.conf, ÐºÐ¾Ñ\82оÑ\80ое Ð½Ðµ "
-"измениÑ\82Ñ\81Ñ\8f Ð¾Ñ\82 Ð¿ÐµÑ\80еименованиÑ\8f Ð·Ð´ÐµÑ\81Ñ\8c."
+"ЭÑ\82оÑ\82 Ð¿Ð°ÐºÐµÑ\82 Ð¼Ð¾Ð´Ð¾Ð² Ð¸Ð¼ÐµÐµÑ\82 Ð¸Ð¼Ñ\8f, Ñ\8fвно Ñ\83казанное Ð² modpack.conf, ÐºÐ¾Ñ\82оÑ\80ое Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ\82Ñ\81Ñ\8f "
+"от переименования здесь."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "(No description of setting given)"
@@ -614,7 +613,7 @@ msgstr "Отключено"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Edit"
-msgstr "Ð\98зменить"
+msgstr "РедакÑ\82иÑ\80овать"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Enabled"
@@ -633,7 +632,8 @@ msgid "Offset"
 msgstr "Смещение"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Персистенция"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -646,7 +646,7 @@ msgstr "Пожалуйста, введите допустимое число."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Restore Default"
-msgstr "Ð\92оÑ\81Ñ\81Ñ\82ановиÑ\82Ñ\8c Ñ\81Ñ\82андаÑ\80Ñ\82нÑ\8bе Ð½Ð°Ñ\81Ñ\82Ñ\80ойки"
+msgstr "СбÑ\80оÑ\81иÑ\82Ñ\8c Ð·Ð½Ð°Ñ\87ениÑ\8f"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Scale"
@@ -654,7 +654,7 @@ msgstr "Масштаб"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua
 msgid "Search"
-msgstr "Ð\98Ñ\81каÑ\82Ñ\8c"
+msgstr "Ð\9fоиÑ\81к"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Select directory"
@@ -744,15 +744,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Установка мода: не удаётся найти подходящей каталог для пакета модов «$1»"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"Установка мода: неподдерживаемый тип файла или повреждённый архив \"$1\""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Установка мода: файл \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -789,16 +780,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Об этом"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Активные участники"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Ð\94алÑ\8cноÑ\81Ñ\82Ñ\8c Ð¾Ñ\82пÑ\80авлÑ\8fемого Ð°ÐºÑ\82ивного Ð¾Ð±Ñ\8aекÑ\82а"
+msgstr "Ð\90кÑ\82ивнÑ\8bй Ð²Ð¸Ð·Ñ\83ализаÑ\82оÑ\80:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -822,7 +812,7 @@ msgstr "Прошлые участники"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Core Developers"
-msgstr "Прошлые разработчики"
+msgstr "Прошлые основные разработчики"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Browse online content"
@@ -870,7 +860,7 @@ msgstr "Публичный сервер"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Bind Address"
-msgstr "Ð\90дÑ\80еÑ\81 Ð¿Ñ\80ивÑ\8fзки"
+msgstr "Ð\9fÑ\80ивÑ\8fзаÑ\82Ñ\8c Ð\90дÑ\80еÑ\81"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Creative Mode"
@@ -933,9 +923,8 @@ msgid "Start Game"
 msgstr "Начать игру"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Адрес: "
+msgstr "Адрес"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -951,22 +940,20 @@ msgstr "Режим творчества"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Урон"
+msgstr "Урон / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Убрать из избранного"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Ð\92 Ð¸Ð·Ð±Ñ\80аннÑ\8bе"
+msgstr "Ð\98збÑ\80анное"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Несовместимые серверы"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -977,16 +964,14 @@ msgid "Ping"
 msgstr "Пинг"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Ð\9fÑ\83блиÑ\87нÑ\8bй Ñ\81еÑ\80веÑ\80"
+msgstr "Ð\9fÑ\83блиÑ\87нÑ\8bе Ñ\81еÑ\80веÑ\80Ñ\8b"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Обновить"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Описание сервера"
 
@@ -1031,13 +1016,12 @@ msgid "Connected Glass"
 msgstr "Стёкла без швов"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "ТенÑ\8c Ñ\88Ñ\80иÑ\84Ñ\82а"
+msgstr "Ð\94инамиÑ\87еÑ\81кие Ñ\82ени"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Динамические тени: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1045,15 +1029,15 @@ msgstr "Красивая листва"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Высокое"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Низкое"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Среднее"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1080,8 +1064,9 @@ msgid "Node Outlining"
 msgstr "Обводка нод"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "None"
-msgstr "Ð\9dеÑ\82"
+msgstr "Ð\9dиÑ\87его"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Leaves"
@@ -1127,10 +1112,6 @@ msgstr "Мягкое освещение"
 msgid "Texturing:"
 msgstr "Текстурирование:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Для включения шейдеров необходим драйвер OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Тональное отображение"
@@ -1145,11 +1126,11 @@ msgstr "Трилинейная фильтрация"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Ультравысокое"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Очень низкое"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1163,7 +1144,7 @@ msgstr "Волнистые жидкости"
 msgid "Waving Plants"
 msgstr "Покачивание растений"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Тайм-аут соединения."
 
@@ -1192,8 +1173,8 @@ msgid "Connection error (timed out?)"
 msgstr "Ошибка соединения (тайм-аут?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Невозможно найти или загрузить игру \""
+msgid "Could not find or load game"
+msgstr "Не удалось найти или загрузить игру: "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1235,14 +1216,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Адрес: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Режим творчества: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Урон: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Режим: "
@@ -1264,6 +1237,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Имя сервера: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Произошла ошибка сериализации:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Доступ запрещен. Причина: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Автобег отключён"
@@ -1272,6 +1254,22 @@ msgstr "Автобег отключён"
 msgid "Automatic forward enabled"
 msgstr "Автобег включён"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Границы блока скрыты"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Границы показаны для всех блоков"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Границы показаны для текущего блока"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Границы показаны для блоков рядом"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Обновление камеры выключено"
@@ -1280,6 +1278,10 @@ msgstr "Обновление камеры выключено"
 msgid "Camera update enabled"
 msgstr "Обновление камеры включено"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Нельзя показать границы блока (нужна привилегия 'basic_debug')"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Изменить пароль"
@@ -1292,6 +1294,10 @@ msgstr "Режим кино отключён"
 msgid "Cinematic mode enabled"
 msgstr "Режим кино включён"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Клиент отключился"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Клиентские моды отключены"
@@ -1300,6 +1306,10 @@ msgstr "Клиентские моды отключены"
 msgid "Connecting to server..."
 msgstr "Подключение к серверу..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Сбой соединения по неизвестной причине"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Продолжить"
@@ -1337,6 +1347,11 @@ msgstr ""
 "- Колесо мыши: выбор предмета\n"
 "- %s: чат\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Не удалось разрешить адрес: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Создание клиента..."
@@ -1467,9 +1482,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Миникарта сейчас отключена игрой или модом"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Ð\9eдиноÑ\87наÑ\8f Ð¸Ð³Ñ\80а"
+msgstr "Ð\9cÑ\83лÑ\8cÑ\82иплееÑ\80"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1543,6 +1557,21 @@ msgstr "Звук не поддерживается в этой сборке"
 msgid "Sound unmuted"
 msgstr "Звук включён"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Вероятно, на сервере используется другая версия %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Не удаётся подключиться к %s, так как IPv6 отключён"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Не удаётся прослушать %s, так как IPv6 отключён"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1634,7 +1663,7 @@ msgstr "Выполнить"
 
 #: src/client/keycode.cpp
 msgid "Help"
-msgstr "СпÑ\80авка"
+msgstr "Ð\9fомоÑ\89Ñ\8c"
 
 #: src/client/keycode.cpp
 msgid "Home"
@@ -1715,7 +1744,7 @@ msgstr "Доп. клав. -"
 
 #: src/client/keycode.cpp
 msgid "Numpad ."
-msgstr "Цифр. клав. '.'"
+msgstr "Цифр. кл. ."
 
 #: src/client/keycode.cpp
 msgid "Numpad /"
@@ -1829,7 +1858,7 @@ msgstr "Shift"
 
 #: src/client/keycode.cpp
 msgid "Sleep"
-msgstr "Sleep"
+msgstr "Спать"
 
 #: src/client/keycode.cpp
 msgid "Snapshot"
@@ -1877,6 +1906,14 @@ msgstr "Миникарта в поверхностном режиме, увел
 msgid "Minimap in texture mode"
 msgstr "Минимальный размер текстуры"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Не удалось открыть веб-страницу"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Открытие страницы"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Пароли не совпадают!"
@@ -1906,9 +1943,8 @@ msgid "Proceed"
 msgstr "Продолжить"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "Использовать = спуск"
+msgstr "\"Aux1\" = спуск"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1920,7 +1956,7 @@ msgstr "Автопрыжок"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1928,11 +1964,11 @@ msgstr "Назад"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Границы блока"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
-msgstr "Ð\98змениÑ\82Ñ\8c ÐºÐ°Ð¼ÐµÑ\80Ñ\83"
+msgstr "СмениÑ\82Ñ\8c Ñ\80акÑ\83Ñ\80Ñ\81"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Chat"
@@ -2026,7 +2062,7 @@ msgstr "Вкл/выкл игровой интерфейс"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle chat log"
-msgstr "Вкл/выкл историю чата"
+msgstr "Включить лог чата"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle fast"
@@ -2054,7 +2090,7 @@ msgstr "По наклону взгляда"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "press key"
-msgstr "нажмите ..."
+msgstr "нажмите клавишу"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Change"
@@ -2081,8 +2117,9 @@ msgid "Muted"
 msgstr "Заглушить"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Громкость звука: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Громкость звука: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2107,14 +2144,13 @@ msgstr ""
 "касания."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Использовать виртуальный джойстик для активации кнопки \"aux\".\n"
-"Если включено, виртуальный джойстик также будет нажимать кнопку \"aux\", "
+"(Android) Использовать виртуальный джойстик для активации кнопки \"Aux1\".\n"
+"Если включено, виртуальный джойстик также будет нажимать кнопку \"Aux1\", "
 "когда будет находиться за пределами основного колеса."
 
 #: src/settings_translation_file.cpp
@@ -2255,14 +2291,13 @@ msgid ""
 msgstr ""
 "Поддержка 3D.\n"
 "Сейчас поддерживаются:\n"
-"-    none: 3D-режим отключён.\n"
-"-    anaglyph: голубой/пурпурный цвет в 3D.\n"
-"-    interlaced: чётные/нечётные линии отображают два разных кадра для "
-"экранов, поддерживающих поляризацию.\n"
-"-    topbottom: Разделение экрана верх/низ.\n"
-"-    sidebyside: Разделение экрана право/лево.\n"
+"-    none: Нет.\n"
+"-    anaglyph: Анаглифные очки.\n"
+"-    interlaced: Поляризационные 3d-очки.\n"
+"-    topbottom: Разделение экрана по горизонтали.\n"
+"-    sidebyside: Разделение экрана по диагонали.\n"
 "-    crossview: 3D на основе автостереограммы.\n"
-"-    pageflip: 3D на основе четырёхкратной буферизации.\n"
+"-    pageflip: Четырёхкратная буферизация.\n"
 "Примечание: в режиме interlaced шейдеры должны быть включены."
 
 #: src/settings_translation_file.cpp
@@ -2287,7 +2322,7 @@ msgstr "ABM интервал"
 
 #: src/settings_translation_file.cpp
 msgid "ABM time budget"
-msgstr "Ð\91Ñ\8eджет времени ABM"
+msgstr "Ð\9bимит времени ABM"
 
 #: src/settings_translation_file.cpp
 msgid "Absolute limit of queued blocks to emerge"
@@ -2339,6 +2374,12 @@ msgstr ""
 "Настройка dpi (плотности точек на дюйм) для вашего экрана (не для X11, "
 "только для Android). Например для мониторов с разрешением в 4k."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Настройка обнаруженной плотности дисплея, используется для масштабирования "
+"элементов интерфейса."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2368,11 +2409,11 @@ msgid ""
 "This only has significant effect on daylight and artificial\n"
 "light, it has very little effect on natural night light."
 msgstr ""
-"Изменяет кривую света, применяя к ней \"гамма-коррекцию\".\n"
-"Ð\91олее Ð²Ñ\8bÑ\81окие Ð·Ð½Ð°Ñ\87ениÑ\8f Ð´ÐµÐ»Ð°Ñ\8eÑ\82 Ñ\81Ñ\80едний Ð¸ Ñ\81лабÑ\8bй Ñ\81веÑ\82 Ñ\8fÑ\80Ñ\87е.\n"
-"Значение \"1.0\" оставляет кривую света без изменений.\n"
-"Ð\97наÑ\87иÑ\82елÑ\8cнÑ\8bй Ñ\8dÑ\84Ñ\84екÑ\82 Ð²Ð¸Ð´ÐµÐ½ Ñ\82олÑ\8cко Ð½Ð° Ð´Ð½ÐµÐ²Ð½Ð¾Ð¼ Ð¸ Ð¸Ñ\81кÑ\83Ñ\81Ñ\81Ñ\82венном\n"
-"освещении, почти не влияет на естественный ночной свет."
+"Изменяет кривую света, применяя к ней гамма-коррекцию.\n"
+"Ð\91олее Ð²Ñ\8bÑ\81окие Ð·Ð½Ð°Ñ\87ениÑ\8f Ð´ÐµÐ»Ð°Ñ\8eÑ\82 Ñ\81Ñ\80едние Ð¸ Ð½Ð¸Ð·ÐºÐ¸Ðµ Ñ\83Ñ\80овни Ñ\81веÑ\82а Ð±Ð¾Ð»ÐµÐµ Ñ\8fÑ\80кими.\n"
+"Значение 1.0 оставляет кривую света без изменений.\n"
+"ЭÑ\82о Ð·Ð½Ð°Ñ\87иÑ\82елÑ\8cно Ð²Ð»Ð¸Ñ\8fеÑ\82 Ñ\82олÑ\8cко Ð½Ð° Ð´Ð½ÐµÐ²Ð½Ð¾Ð¹ Ð¸ Ð¸Ñ\81кÑ\83Ñ\81Ñ\81Ñ\82веннÑ\8bй\n"
+"свет, но имеет очень слабый эффект на естественный ночной свет."
 
 #: src/settings_translation_file.cpp
 msgid "Always fly and fast"
@@ -2402,7 +2443,7 @@ msgstr "О сервере"
 
 #: src/settings_translation_file.cpp
 msgid "Announce to this serverlist."
-msgstr "Ð\90нонÑ\81иÑ\80оваÑ\82Ñ\8c Ð½Ð° Ñ\8dÑ\82оÑ\82 Ñ\81пиÑ\81ок Ñ\81еÑ\80веÑ\80ов."
+msgstr "Ð\9eповеÑ\89ение Ð² Ñ\8dÑ\82оÑ\82 Ñ\81еÑ\80веÑ\80-лиÑ\81Ñ\82."
 
 #: src/settings_translation_file.cpp
 msgid "Append item name"
@@ -2461,7 +2502,7 @@ msgstr "Автоматическая кнопка вперед"
 
 #: src/settings_translation_file.cpp
 msgid "Automatically jump up single-node obstacles."
-msgstr "Ð\90вÑ\82омаÑ\82иÑ\87еÑ\81кий Ð¿Ð¾Ð´Ñ\8aем Ð½Ð° Ð¾Ð´Ð¸Ð½Ð¾Ñ\87нÑ\8bе Ð±Ð»Ð¾ÐºÐ¸."
+msgstr "Ð\90вÑ\82омаÑ\82иÑ\87еÑ\81кий Ð¿Ð¾Ð´Ñ\8aем Ð½Ð° Ð¾Ð´Ð¸Ð½Ð¾Ñ\87нÑ\8bе Ð½Ð¾Ð´Ñ\8b."
 
 #: src/settings_translation_file.cpp
 msgid "Automatically report to the serverlist."
@@ -2476,14 +2517,12 @@ msgid "Autoscaling mode"
 msgstr "Режим автоматического масштабирования"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Ð\9aнопка Ð¿Ñ\80Ñ\8bжка"
+msgstr "Ð\9aлавиÑ\88а Aux1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Клавиша «Использовать» для спуска"
+msgstr "Клавиша Aux1 для подъема/спуска"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2636,9 +2675,12 @@ msgstr ""
 "где 0.0 — минимальный уровень света, а 1.0 — максимальный."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Максимальное количество сообщений в чате (для отключения)"
+msgstr "Порог cообщения команды чата"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Команды чата"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2673,8 +2715,8 @@ msgid "Chat toggle key"
 msgstr "Кнопка переключения чата"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Ð\9aомандÑ\8b Ð² Ñ\87аÑ\82е"
+msgid "Chat weblinks"
+msgstr "Ð\92еб-Ñ\81Ñ\81Ñ\8bлки Ñ\87аÑ\82а"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2692,6 +2734,12 @@ msgstr "Кнопка переключения в кинематографиче
 msgid "Clean transparent textures"
 msgstr "Очистить прозрачные текстуры"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr "Нажимающиеся ссылки (СКМ или Ctrl+ЛКМ) включены в консоли."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Клиент"
@@ -2737,9 +2785,8 @@ msgid "Colored fog"
 msgstr "Цветной туман"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Цветной туман"
+msgstr "Цветные тени"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2774,13 +2821,42 @@ msgid ""
 "functions even when mod security is on (via request_insecure_environment())."
 msgstr ""
 "Разделённый запятыми список доверенных модов, которым разрешён\n"
-"доступ к небезопасным функциям, даже когда включена защита модов\n"
-"(через request_insecure_environment())."
+"доступ к небезопасным функциям, даже когда включена защита модов (через "
+"request_insecure_environment())."
 
 #: src/settings_translation_file.cpp
 msgid "Command key"
 msgstr "Команда"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Уровень сжатия ZLib для использования при сохранении картографических блоков "
+"на диске.\n"
+"-1 - уровень сжатия Zlib по умолчанию\n"
+"0 - без компрессора, самый быстрый\n"
+"9 - лучшее сжатие, самое медленное\n"
+"(уровни 1-3 используют \"быстрый\" метод Zlib, 4-9 используют обычный метод)"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Уровень сжатия ZLib для использования при отправке блоков карты клиенту.\n"
+"-1 - уровень сжатия Zlib по умолчанию\n"
+"0 - без компрессора, самый быстрый\n"
+"9 - лучшее сжатие, самое медленное\n"
+"(уровни 1-3 используют \"быстрый\" метод Zlib, 4-9 используют обычный метод)"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Стёкла без швов"
@@ -2882,10 +2958,10 @@ msgstr "Прозрачность перекрестия"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Прозрачность прицела (от 0 (прозрачно) до 255 (непрозрачно)).\n"
-"Также контролирует цвет перекрестия объекта"
+"Также контролирует перекрестия объекта."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2964,11 +3040,15 @@ msgid "Default stack size"
 msgstr "Размер стака по умолчанию"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Определите качество фильтрации теней\n"
+"Это имитирует эффект мягких теней, применяя PCF или пуассоновский диск\n"
+"но также использует больше ресурсов."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3097,6 +3177,10 @@ msgstr "Отключить анти-чит"
 msgid "Disallow empty passwords"
 msgstr "Запретить пустой пароль"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Коэффициент масштабирования плотности отображения"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Доменное имя сервера, отображаемое в списке серверов."
@@ -3135,7 +3219,7 @@ msgid ""
 "Required for IPv6 connections to work at all."
 msgstr ""
 "Включить поддержку IPv6 (для клиента и сервера).\n"
-"Ð\9dеобÑ\85одимо Ð´Ð»Ñ\8f Ñ\80абоÑ\82Ñ\8b IPv6-Ñ\81оединений."
+"ТÑ\80ебÑ\83еÑ\82Ñ\81Ñ\8f Ð´Ð»Ñ\8f Ñ\82ого, Ñ\87Ñ\82обÑ\8b Ð²Ð¾Ð¾Ð±Ñ\89е Ñ\81оединÑ\8fÑ\82Ñ\8cÑ\81Ñ\8f Ð¿Ð¾ IPv6."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3146,10 +3230,24 @@ msgstr ""
 "Эта поддержка является экспериментальной и API может измениться."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Включить фильтрацию диска Пуассона.\n"
+"По истине использует диск Пуассона для создания \"мягких теней\". Иначе "
+"используется фильтрация PCF."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Включить цветные тени.\n"
+"На истинно полупрозрачных узлах отбрасываются цветные тени. Это дорого."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3175,13 +3273,6 @@ msgstr "Включить защиту модов"
 msgid "Enable players getting damage and dying."
 msgstr "Включить получение игроками урона и их смерть."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Включить случайный ввод пользователя (только для тестов)."
@@ -3295,6 +3386,15 @@ msgstr ""
 "настройки звука не будут работать.\n"
 "Изменение этого параметра требует перезапуска."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+"Обеспечивает компромисс, который снижает использование ЦП или увеличивает "
+"производительность рендеринга\n"
+"ценой мелких визуальных дефектов, не влияющих на геймплей."
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Интервал печати данных профилирования движка"
@@ -3356,12 +3456,11 @@ msgid "Fast movement"
 msgstr "Быстрое перемещение"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Быстрое перемещение (с помощью клавиши «Использовать»).\n"
+"Быстрое перемещение (с помощью клавиши \"Aux1\").\n"
 "Это требует привилегию 'fast' на сервере."
 
 #: src/settings_translation_file.cpp
@@ -3394,17 +3493,19 @@ msgid "Filmic tone mapping"
 msgstr "Кинематографическое тональное отображение"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
 "light edges to transparent textures. Apply a filter to clean that up\n"
 "at texture load time. This is automatically enabled if mipmapping is enabled."
 msgstr ""
-"Отфильтрованные текстуры могут смешивать значения RGB с полностью\n"
-"прозрачными соседними, которые оптимизаторы PNG обычно отбрасывают.\n"
-"Иногда это может привести к тёмным или светлым краям полупрозрачных\n"
-"текстур. Примените этот фильтр, чтобы исправить текстуру во время загрузки."
+"Фильтрованные текстуры могут смешивать значения RGB с полностью прозрачными "
+"соседними,\n"
+"которые оптимизаторы PNG обычно отбрасывают, что часто приводит к темным "
+"или\n"
+"светлым краям прозрачных текстур. Примените фильтр для очистки\n"
+"во время загрузки текстуры. Это автоматически включается, если включен "
+"mipmapping."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3495,11 +3596,18 @@ msgid "Font size"
 msgstr "Размер шрифта"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+#, fuzzy
+msgid "Font size divisible by"
+msgstr "Размер шрифта, кратный"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Размер стандартного шрифта в пунктах (pt)."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Размер моноширинного шрифта в пунктах (pt)."
 
 #: src/settings_translation_file.cpp
@@ -3510,6 +3618,24 @@ msgstr ""
 "Размер шрифта последнего чата и подсказки чата в точке (pt).\n"
 "Значение 0 будет использовать размер шрифта по умолчанию."
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+"Для шрифтов пиксельного стиля, которые плохо масштабируются, это "
+"гарантирует, что размеры шрифта, используемые\n"
+"с этим шрифтом всегда будут кратны этому значению в пикселях. Например,\n"
+"пиксельный шрифт высотой 16 пикселей должен иметь значение 16, поэтому он "
+"всегда будет иметь только\n"
+"16, 32, 48 и т.д., поэтому мод, запрашивающий размер 25, получит 32."
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3573,10 +3699,6 @@ msgstr "Тип фрактала"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Часть видимого расстояния, на которой начинает появляться туман"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Шрифты FreeType"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3630,10 +3752,11 @@ msgid "Global callbacks"
 msgstr "Глобальные обратные вызовы"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Глобальные атрибуты генерации карт.\n"
 "В картогенераторе v6 флаг «decorations» не влияет на деревья и траву\n"
@@ -3669,7 +3792,7 @@ msgstr "Уровень земли"
 
 #: src/settings_translation_file.cpp
 msgid "Ground noise"
-msgstr "ШÑ\83м Ð³Ñ\80Ñ\83нÑ\82а"
+msgstr "ШÑ\83м Ð·ÐµÐ¼Ð»Ð¸"
 
 #: src/settings_translation_file.cpp
 msgid "HTTP mods"
@@ -3719,10 +3842,11 @@ msgid "Heat noise"
 msgstr "Шум теплоты"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Высота окна при запуске."
+msgstr ""
+"Компонент высоты начального размера окна. Игнорируется в полноэкранном "
+"режиме."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3794,135 +3918,135 @@ msgstr "Предыдущий предмет на горячей панели"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 1 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 1 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 1"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 10 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 10 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 10"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 11 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 11 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 11"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 12 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 12 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 12"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 13 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 13 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 13"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 14 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 14 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 14"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 15 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 15 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 15"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 16 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 16 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 16"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 17 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 17 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 17"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 18 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 18 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 18"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 19 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 19 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 19"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 2 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 2 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 2"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 20 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 20 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 20"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 21 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 21 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 21"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 22 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 22 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 22"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 23 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 23 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 23"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 24 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 24 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 24"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 25 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 25 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 25"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 26 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 26 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 26"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 27 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 27 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 27"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 28 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 28 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 28"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 29 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 29 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 29"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 3 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 3 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 3"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 30 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 30 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 30"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 31 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 31 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 31"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 32 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 32 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 32"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 4 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 4 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 4"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 5 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 5 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 5"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 6 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 6 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 6"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 7 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 7 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 7"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 8 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 8 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 8"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 9 key"
-msgstr "Ð\9fÑ\80едмеÑ\82 9 Ð½Ð° Ð³Ð¾Ñ\80Ñ\8fÑ\87ей Ð¿Ð°Ð½ÐµÐ»Ð¸"
+msgstr "Ð\91Ñ\8bÑ\81Ñ\82Ñ\80аÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° 9"
 
 #: src/settings_translation_file.cpp
 msgid "How deep to make rivers."
-msgstr "Ð\9aак глубоко делать реки."
+msgstr "Ð\9dаÑ\81колÑ\8cко глубоко делать реки."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3944,7 +4068,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "How wide to make rivers."
-msgstr "Ð\9dаÑ\81колÑ\8cко Ñ\88иÑ\80окими делать реки."
+msgstr "Ð\9dаÑ\81колÑ\8cко Ñ\88иÑ\80око делать реки."
 
 #: src/settings_translation_file.cpp
 msgid "Humidity blend noise"
@@ -3975,13 +4099,13 @@ msgstr ""
 "чтобы не тратить мощность процессора впустую."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Если отключено, кнопка «Использовать» активирует быстрый полёт, если "
-"одновременно включены режим быстрого перемещения и режим полёта."
+"Если отключено, кнопка \"Aux1\" используется для быстрого полета, если режим "
+"полёта и быстрый режим\n"
+"включены."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4007,14 +4131,14 @@ msgstr ""
 "Требует наличие привилегии «noclip» на сервере."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Если включено, то для спуска (в воде или при полёте) будет задействована "
-"клавиша «Использовать», а не «Красться»."
+"Если включено, клавиша \"Aux1\" вместо клавиши \"Sneak\" используется для "
+"подъема вниз и\n"
+"спуска."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4072,6 +4196,8 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Если выполнение команды чата занимает больше указанного времени в\n"
+"секундах, добавьте информацию о времени в сообщение команды чата"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4126,7 +4252,7 @@ msgstr ""
 "Обычно это нужно тем, кто пишет код для движка"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr "Выполнять команды в чате при регистрации."
 
 #: src/settings_translation_file.cpp
@@ -4216,7 +4342,7 @@ msgid "Joystick button repetition interval"
 msgstr "Интервал повторного клика кнопкой джойстика"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Мертвая зона джойстика"
 
 #: src/settings_translation_file.cpp
@@ -5332,8 +5458,8 @@ msgstr "Интервал сохранения карты"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
-msgstr "Ð\98нÑ\82еÑ\80вал Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ\8f Ð¶Ð¸Ð´ÐºÐ¾Ñ\81Ñ\82ей"
+msgid "Map shadows update frames"
+msgstr "Ð\92Ñ\80емÑ\8f Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ\8f ÐºÐ°Ñ\80Ñ\82Ñ\8b"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5446,7 +5572,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Максимальное расстояние для отрисовки теней."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5537,7 +5663,7 @@ msgid ""
 msgstr ""
 "Максимальное количество пакетов, отправляемых за шаг. Если у вас медленное "
 "подключение,\n"
-"попробуйте уменьшить его, но не устанавливайте ниже значения клиента, "
+"попробуйте уменьшить его, но не устанавливайте ниже значения клиента,\n"
 "умноженного на два."
 
 #: src/settings_translation_file.cpp
@@ -5581,19 +5707,20 @@ msgstr ""
 "0 для отключения очереди и -1 для неограниченного размера."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Максимум времени (в миллисекундах), которое может занять загрузка (например, "
-"мода)."
+"Максимальное время загрузки файла (например, загрузки мода), указанное в "
+"миллиÑ\81екÑ\83ндаÑ\85."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Максимальное время, которое может занять интерактивный запрос (например, "
+"получение списка серверов), указывается в миллисекундах."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5656,7 +5783,7 @@ msgid "Mod channels"
 msgstr "Каналы модификаций"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr "Изменяет размер элементов игрового интерфейса."
 
 #: src/settings_translation_file.cpp
@@ -5667,6 +5794,11 @@ msgstr "Путь к моноширинному шрифту"
 msgid "Monospace font size"
 msgstr "Размер моноширинного шрифта"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Размер моноширинного шрифта"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Шум высоты гор"
@@ -5809,9 +5941,10 @@ msgstr ""
 "Для большинства пользователей наилучшим значением может быть '1'."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Количество дополнительных блоков, которые могут сразу быть загружены /"
@@ -5831,7 +5964,7 @@ msgstr "Непрозрачные жидкости"
 #: src/settings_translation_file.cpp
 msgid ""
 "Opaqueness (alpha) of the shadow behind the default font, between 0 and 255."
-msgstr "Ð\9dепÑ\80озÑ\80аÑ\87ноÑ\81Ñ\82Ñ\8c (алÑ\8cÑ\84а) Ñ\82ени Ð¿Ð¾Ð·Ð°Ð´Ð¸ Ñ\88Ñ\80иÑ\84Ñ\82а Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e, между 0 и 255."
+msgstr "Ð\9fÑ\80озÑ\80аÑ\87ноÑ\81Ñ\82Ñ\8c Ñ\82ени Ñ\81зади Ñ\81Ñ\82андаÑ\80Ñ\82ного Ñ\88Ñ\80иÑ\84Ñ\82а, между 0 и 255."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5843,10 +5976,13 @@ msgstr ""
 "форма уже открыта."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Необязательное переопределение цвета ссылки в чате."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5876,13 +6012,12 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid "Path to texture directory. All textures are first searched from here."
 msgstr ""
-"Ð\9fÑ\83Ñ\82Ñ\8c Ð´Ð¾ ÐºÐ°Ñ\82алога Ñ\81 Ñ\82екÑ\81Ñ\82Ñ\83Ñ\80ами. Ð\92Ñ\81е Ñ\82екÑ\81Ñ\82Ñ\83Ñ\80Ñ\8b Ð² Ð¿ÐµÑ\80вÑ\83Ñ\8e Ð¾Ñ\87еÑ\80едÑ\8c Ð±ÐµÑ\80Ñ\83Ñ\82Ñ\81Ñ\8f Ð¾Ñ\82 сюда."
+"Ð\9fÑ\83Ñ\82Ñ\8c Ðº Ð´Ð¸Ñ\80екÑ\82оÑ\80ии Ñ\81 Ñ\82екÑ\81Ñ\82Ñ\83Ñ\80ами. Ð\92Ñ\81е Ñ\82екÑ\81Ñ\82Ñ\83Ñ\80Ñ\8b Ð² Ð¿ÐµÑ\80вÑ\83Ñ\8e Ð¾Ñ\87еÑ\80едÑ\8c Ð±ÐµÑ\80Ñ\83Ñ\82Ñ\81Ñ\8f Ð¾Ñ\82сюда."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Путь к шрифту по умолчанию.\n"
@@ -5892,10 +6027,9 @@ msgstr ""
 "Резервный шрифт будет использоваться, если шрифт не может быть загружен."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Путь к моноширинному шрифту.\n"
@@ -5930,7 +6064,7 @@ msgstr "Режим движения вниз/вверх по направлен
 
 #: src/settings_translation_file.cpp
 msgid "Place key"
-msgstr "Клавиша «Разместить»"
+msgstr "Клавиша положить"
 
 #: src/settings_translation_file.cpp
 msgid "Place repetition interval"
@@ -5957,9 +6091,8 @@ msgid "Player versus player"
 msgstr "Режим «Игрок против игрока» (PvP)"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Ð\91илинейная фильтрация"
+msgstr "Ð\9fÑ\83аÑ\81Ñ\81оновÑ\81кая фильтрация"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6014,11 +6147,12 @@ msgid "Prometheus listener address"
 msgstr "адрес приёмника Prometheus"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Адрес приёмника Prometheus.\n"
 "Если мой тест скомпилирован с включенной опцией ENABLE_PROMETHEUS,\n"
@@ -6056,7 +6190,7 @@ msgstr "Недавние сообщения чата"
 
 #: src/settings_translation_file.cpp
 msgid "Regular font path"
-msgstr "СÑ\82андаÑ\80Ñ\82нÑ\8bй Ð¿Ñ\83Ñ\82Ñ\8c Ñ\88Ñ\80иÑ\84Ñ\82а"
+msgstr "Ð\9fÑ\83Ñ\82Ñ\8c Ðº Ð¾Ð±Ñ\8bÑ\87номÑ\83 Ñ\88Ñ\80иÑ\84Ñ\82Ñ\83"
 
 #: src/settings_translation_file.cpp
 msgid "Remote media"
@@ -6197,9 +6331,9 @@ msgstr ""
 "Масштабировать интерфейс, используя заданное пользователем значение.\n"
 "Использовать метод ближайшего соседа и антиалиасинг, чтобы масштабировать "
 "интерфейс.\n"
-"Это сгладит некоторые острые углы и смешает пиксели при уменьшении масштаба "
-"за Ñ\81Ñ\87Ñ\91Ñ\82\n"
-"размывания пикселей на гранях при масштабировании на нецелые размеры."
+"Это сгладит некоторые острые углы и смешает\n"
+"пикÑ\81ели Ð¿Ñ\80и Ñ\83менÑ\8cÑ\88ении Ð¼Ð°Ñ\81Ñ\88Ñ\82аба Ð·Ð° Ñ\81Ñ\87Ñ\91Ñ\82 Ñ\80азмÑ\8bваниÑ\8f\n"
+"пикселей на гранях при масштабировании на нецелые размеры."
 
 #: src/settings_translation_file.cpp
 msgid "Screen height"
@@ -6362,31 +6496,33 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
+"Установите силу тени.\n"
+"Меньшее значение означает более светлые тени, большее значение означает "
+"более тёмные тени."
 
 #: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
-#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Установить размер радиуса мягкой тени.\n"
+"Меньшие значения означают более резкие тени, большие значения более мягкие.\n"
+"Минимальное значение 1,0 и максимальное 10,0"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Установка наклона орбиты Солнца/Луны в градусах.\n"
+"Значение 0 означает отсутствие наклона / вертикальную орбиту.\n"
+"Минимальное значение 0.0 и максимальное значение 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
@@ -6424,6 +6560,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Устанавливает качество текстуры тени в 32 бита.\n"
+"При значении false будет использоваться 16-битная текстура.\n"
+"Это может вызвать гораздо больше артефактов в тени."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6437,26 +6576,25 @@ msgid ""
 "This only works with the OpenGL video backend."
 msgstr ""
 "Шейдеры позволяют использовать дополнительные визуальные эффекты и могут "
-"увеличить производительность на некоторых видеокартах.\n"
+"увеличить\n"
+"производительность на некоторых видеокартах.\n"
 "Работают только с видео-бэкендом OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Ð\9aаÑ\87еÑ\81Ñ\82во Ñ\81кÑ\80инÑ\88оÑ\82а"
+msgstr "Ð\9aаÑ\87еÑ\81Ñ\82во Ñ\82еневого Ñ\84илÑ\8cÑ\82Ñ\80а"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Максимальное расстояние карты теней в узлах для рендеринга теней"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "Текстура карты теней в 32 битах"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Ð\9cинималÑ\8cнÑ\8bй Ñ\80азмеÑ\80 Ñ\82екÑ\81Ñ\82Ñ\83Ñ\80Ñ\8b"
+msgstr "РазмеÑ\80 Ñ\82екÑ\81Ñ\82Ñ\83Ñ\80Ñ\8b ÐºÐ°Ñ\80Ñ\82Ñ\8b Ñ\82еней"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6468,7 +6606,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Сила тени"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6491,7 +6629,8 @@ msgstr ""
 "Требует перезапуска после изменения."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+#, fuzzy
+msgid "Show name tag backgrounds by default"
 msgstr "Отображать фон у табличек с именами"
 
 #: src/settings_translation_file.cpp
@@ -6529,7 +6668,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Наклон орбиты небесного тела"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6590,9 +6729,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Скорость ходьбы украдкой в нодах в секунду."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Ð\9fÑ\80озÑ\80аÑ\87ноÑ\81Ñ\82Ñ\8c Ñ\82ени Ñ\88Ñ\80иÑ\84Ñ\82а"
+msgstr "РадиÑ\83Ñ\81 Ð¼Ñ\8fгкой Ñ\82ени"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6621,6 +6759,19 @@ msgstr ""
 "Обратите внимание, что моды или игры могут явно установить стек для "
 "определенных (или всех) предметов."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Распространяет полное обновление карты теней на заданное количество кадров.\n"
+"Более высокие значения могут сделать тени нестабильными, более низкие "
+"значения\n"
+"будут потреблять больше ресурсов.\n"
+"Минимальное значение: 1; максимальное значение: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6755,11 +6906,15 @@ msgid "Texture path"
 msgstr "Путь к текстурам"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Размер текстуры для рендеринга карты теней.\n"
+"Это должно быть число, кратное двум.\n"
+"Большие числа создают более качественные тени, но они и более дорогие."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6784,7 +6939,8 @@ msgid "The URL for the content repository"
 msgstr "Адрес сетевого репозитория"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+#, fuzzy
+msgid "The dead zone of the joystick"
 msgstr "Мертвая зона джойстика"
 
 #: src/settings_translation_file.cpp
@@ -6862,7 +7018,6 @@ msgstr ""
 "Это должно быть настроено вместе с active_object_send_range_blocks."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6871,17 +7026,19 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Программный интерфейс визуализации для Irrlicht.\n"
-"После изменения этого параметра потребуется перезапуск.\n"
-"Примечание: Если не уверены, используйте OGLES1 для Android, иначе\n"
-"приложение может не запуститься. На других платформах рекомендуется\n"
-"OpenGL. Шейдеры поддерживаются OpenGL (только на десктопах) и OGLES2 "
-"(экспериментально)"
+"Бэкэнд рендеринга.\n"
+"После изменения этого параметра требуется перезагрузка.\n"
+"Примечание: На Android, если вы не уверены, используйте OGLES1! В противном "
+"случае приложение может не запуститься.\n"
+"На других платформах рекомендуется использовать OpenGL.\n"
+"Шейдеры поддерживаются OpenGL (только для настольных компьютеров) и OGLES2 "
+"(экспериментальный)"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Чувствительность осей джойстика для перемещения\n"
 "взгляда в игре."
@@ -6930,8 +7087,8 @@ msgid ""
 "The time in seconds it takes between repeated node placements when holding\n"
 "the place button."
 msgstr ""
-"Ð\97адеÑ\80жка Ð¿ÐµÑ\80ед Ð¿Ð¾Ð²Ñ\82оÑ\80нÑ\8bм Ñ\80азмеÑ\89ением Ð±Ð»Ð¾ÐºÐ° в секундах\n"
-"при удержании клавиши размещения"
+"Ð\97адеÑ\80жка Ð¿ÐµÑ\80ед Ð¿Ð¾Ð²Ñ\82оÑ\80нÑ\8bм Ñ\80азмеÑ\89ением Ð½Ð¾Ð´Ñ\8b в секундах\n"
+"при удержании клавиши размещения."
 
 #: src/settings_translation_file.cpp
 msgid "The type of joystick"
@@ -7004,6 +7161,10 @@ msgstr "Задержка подсказки"
 msgid "Touch screen threshold"
 msgstr "Порог сенсорного экрана"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "Компромиссы для производительности"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Шум деревьев"
@@ -7083,14 +7244,15 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Использовать билинейную фильтрацию для масштабирования текстур."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
-"Использовать MIP-текстурирование для масштабирования текстур.\n"
-"Может немного увеличить производительность, особенно при\n"
-"использовании пакета текстур высокого разрешения.\n"
+"Использовать MIP-текстурирование для масштабирования текстур. Может немного "
+"увеличить производительность,\n"
+"оÑ\81обенно Ð¿Ñ\80и Ð¸Ñ\81полÑ\8cзовании Ð¿Ð°ÐºÐµÑ\82а Ñ\82екÑ\81Ñ\82Ñ\83Ñ\80 Ð²Ñ\8bÑ\81окого Ñ\80азÑ\80еÑ\88ениÑ\8f.\n"
 "Гамма-коррекция при уменьшении масштаба не поддерживается."
 
 #: src/settings_translation_file.cpp
@@ -7214,9 +7376,8 @@ msgid "Viewing range"
 msgstr "Дистанция отрисовки"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Ð\94ополниÑ\82елÑ\8cнаÑ\8f ÐºÐ½Ð¾Ð¿ÐºÐ° Ñ\82Ñ\80иггеÑ\80ов Ð²Ð¸Ñ\80Ñ\82Ñ\83алÑ\8cного Ð´Ð¶Ð¾Ð¹Ñ\81Ñ\82ика"
+msgstr "Ð\92иÑ\80Ñ\82Ñ\83алÑ\8cнÑ\8bй Ð´Ð¶Ð¾Ð¹Ñ\81Ñ\82ик Ð½Ð°Ð¶Ð¸Ð¼Ð°ÐµÑ\82 ÐºÐ½Ð¾Ð¿ÐºÑ\83 Aux1"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7228,7 +7389,7 @@ msgid ""
 "Requires the sound system to be enabled."
 msgstr ""
 "Громкость всех звуков.\n"
-"Требуется включить звуковую систему."
+"Требует включенной звуковой системы."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7288,12 +7449,17 @@ msgstr "Скорость волн волнистых жидкостей"
 
 #: src/settings_translation_file.cpp
 msgid "Waving liquids wavelength"
-msgstr "Ð\94лина Ð²Ð¾Ð»Ð½ Ð²Ð¾Ð»Ð½Ð¸Ñ\81Ñ\82Ñ\8bÑ\85 Ð¶Ð¸Ð´ÐºÐ¾Ñ\81Ñ\82ей"
+msgstr "Ð\94лина Ð²Ð¾Ð»Ð½ Ð½Ð° Ð²Ð¾Ð´Ðµ"
 
 #: src/settings_translation_file.cpp
 msgid "Waving plants"
 msgstr "Покачивание растений"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Цвет выделения"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7325,35 +7491,30 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
 msgstr ""
-"При использовании билинейного, трилинейного или анизотропного фильтра\n"
-"текстуры с низким разрешением могут быть размыты, поэтому происходит\n"
-"автоматическое масштабирование их с интерполяцией по ближайшим соседям,\n"
-"чтобы сохранить чёткие пиксели. Этот параметр определяет минимальный\n"
-"размер для увеличенных текстур. При высоких значениях отображение более\n"
-"чёткое, но требует больше памяти. Рекомендуется значение 2. Установка этого\n"
-"значения выше 1 может не иметь видимого эффекта, если не включена \n"
-"билинейная, трилинейная или анизотропная фильтрация.\n"
-"Также используется как размер базовой текстуры ноды для мирового\n"
-"автомасштабирования текстур."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Использовать ли шрифты FreeType. Поддержка FreeType должна быть включена при "
-"сборке.\n"
-"Если отключено, используются растровые и XML-векторные изображения."
+"При использовании билинейных/трилинейных/анизотропных фильтров текстуры с "
+"низким разрешением\n"
+"могут быть размыты, поэтому автоматически повышайте их масштаб с помощью "
+"ближайших соседей\n"
+"интерполяцией, чтобы сохранить чёткие пиксели. Здесь задается минимальный "
+"размер текстуры\n"
+"для увеличенных текстур; более высокие значения выглядят более чёткими, но "
+"требуют больше\n"
+"памяти.  Рекомендуется использовать значения, кратные 2. Эта настройка "
+"применяется ТОЛЬКО в том случае, если\n"
+"включена билинейная/трилинейная/анизотропная фильтрация.\n"
+"Это значение также используется в качестве базового размера текстуры узла "
+"для автомасштабирования текстур с выравниванием по миру\n"
+"автомасштабирования текстуры."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 "Должен ли отображаться фон бирки по умолчанию.\n"
@@ -7396,10 +7557,11 @@ msgid ""
 "In-game, you can toggle the mute state with the mute key or by using the\n"
 "pause menu."
 msgstr ""
-"Отключить ли звуки. Вы можете включить звуки в любое время, если \n"
-"звуковая система не отключена (enable_sound=false). \n"
-"В игре, вы можете отключить их с помощью клавиши mute\n"
-"или вызывая меню паузы."
+"Нужно ли выключить звуки? Вы можете включить звуки в любое время, если\n"
+"звуковая система не отключена (enable_sound=false).\n"
+"Внутри игры, вы можете включить режим отключения звуков, нажав на клавишу "
+"отключения звуков или используя\n"
+"меню паузы."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -7407,9 +7569,10 @@ msgid ""
 msgstr "Показывать данные отладки (аналогично нажатию F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Ширина компонента начального размера окна."
+msgstr ""
+"Компонент ширины начального размера окна. Игнорируется в полноэкранном "
+"режиме."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7446,13 +7609,14 @@ msgid ""
 "See also texture_min_size.\n"
 "Warning: This option is EXPERIMENTAL!"
 msgstr ""
-"Выровненные по миру текстуры можно масштабировать так, чтобы они\n"
-"охватывали несколько нод. Но сервер может не отправить нужный\n"
-"масштаб, особенно если вы используете специально разработанный\n"
-"пакет текстур; с этим параметром клиент пытается определить масштаб\n"
-"автоматически на основании размера текстуры.\n"
-"Смотрите также texture_min_size.\n"
-"Внимание: Этот параметр ЭКСПЕРИМЕНТАЛЬНЫЙ!"
+"Текстуры с выравниванием по миру могут быть масштабированы так, чтобы "
+"охватить несколько узлов. Однако,\n"
+"сервер может не передать нужный масштаб, особенно если вы используете\n"
+"специально разработанный пакет текстур; при использовании этой опции клиент "
+"пытается\n"
+"определить масштаб автоматически, основываясь на размере текстуры.\n"
+"См. также texture_min_size.\n"
+"Предупреждение: Эта опция является ЭКСПЕРИМЕНТАЛЬНОЙ!"
 
 #: src/settings_translation_file.cpp
 msgid "World-aligned textures mode"
@@ -7510,48 +7674,24 @@ msgstr "Y-уровень нижнего рельефа и морского дн
 msgid "Y-level of seabed."
 msgstr "Y-уровень морского дна."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Уровень сжатия ZLib для использования при сохранении картографических блоков "
-"на диске.\n"
-"-1 - уровень сжатия Zlib по умолчанию\n"
-"0 - без компрессора, самый быстрый\n"
-"9 - лучшее сжатие, самое медленное\n"
-"(уровни 1-3 используют \"быстрый\" метод Zlib, 4-9 используют обычный метод)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Уровень сжатия ZLib для использования при отправке блоков карты клиенту.\n"
-"-1 - уровень сжатия Zlib по умолчанию\n"
-"0 - без компрессора, самый быстрый\n"
-"9 - лучшее сжатие, самое медленное\n"
-"(уровни 1-3 используют \"быстрый\" метод Zlib, 4-9 используют обычный метод)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "Тайм-аут загрузки файла с помощью cURL"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL тайм-аут"
+msgstr "Интерактивный таймаут cURL"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "Лимит одновременных соединений cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Режим творчества: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Урон: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7733,6 +7873,9 @@ msgstr "Лимит одновременных соединений cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Размер резервного шрифта в пунктах (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Шрифты FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Глубина цвета в полноэкранном режиме"
 
@@ -7751,6 +7894,9 @@ msgstr "Лимит одновременных соединений cURL"
 #~ msgid "IPv6 support."
 #~ msgstr "Поддержка IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Установка мода: файл \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Глубина лавы"
 
@@ -7854,6 +8000,17 @@ msgstr "Лимит одновременных соединений cURL"
 #~ msgid "Select Package File:"
 #~ msgstr "Выберите файл дополнения:"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "Установить время обновления теней.\n"
+#~ "Меньшее значение означает, что тени и карта обновляются быстрее, но это "
+#~ "потребляет больше ресурсов.\n"
+#~ "Минимальное значение 0,001 секунды, максимальное 0,2 секунды"
+
 #~ msgid "Shadow limit"
 #~ msgstr "Лимит теней"
 
@@ -7882,6 +8039,9 @@ msgstr "Лимит одновременных соединений cURL"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Этот шрифт будет использован для некоторых языков."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Для включения шейдеров необходим драйвер OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Кино"
 
@@ -7905,6 +8065,15 @@ msgstr "Лимит одновременных соединений cURL"
 #~ msgid "Waving water"
 #~ msgstr "Волны на воде"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Использовать ли шрифты FreeType. Поддержка FreeType должна быть включена "
+#~ "при сборке.\n"
+#~ "Если отключено, используются растровые и XML-векторные изображения."
+
 #, fuzzy
 #~ msgid "Y of upper limit of lava in large caves."
 #~ msgstr "Верхний предел по Y для больших псевдослучайных пещер."
@@ -7918,5 +8087,8 @@ msgstr "Лимит одновременных соединений cURL"
 #~ msgid "Yes"
 #~ msgstr "Да"
 
+#~ msgid "You died."
+#~ msgstr "Ты умер."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index a1f9cd9b3c248bb48e6b54ee0503af342d1add94..22cf8e5706eeed363e00533818adb2a059aafbd9 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-04-21 20:29+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-26 22:42+0000\n"
 "Last-Translator: Marian <daretmavi@gmail.com>\n"
 "Language-Team: Slovak <https://hosted.weblate.org/projects/minetest/minetest/"
 "sk/>\n"
@@ -17,49 +17,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Maximálna veľkosť výstupnej komunikačnej fronty"
+msgstr "Vymaž výstupnú komunikačnú frontu"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Komunikačné príkazy"
+msgstr "Prázdny príkaz."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
 msgstr "Návrat do menu"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Lokálny príkaz"
+msgstr "Chybný príkaz: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Spustený príkaz: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Hra pre jedného hráča"
+msgstr "Zoznam online hráčov"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Hra pre jedného hráča"
+msgstr "Online hráči: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Výstupná komunikačná fronty je teraz prázdna."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Tento príkaz je zakázaný serverom."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -69,42 +63,41 @@ msgstr "Oživiť"
 msgid "You died"
 msgstr "Zomrel si"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Zomrel si"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Lokálny príkaz"
+msgstr "Dostupné príkazy:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Lokálny príkaz"
+msgstr "Dostupné príkazy: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Príkaz nie je k dispozícií: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Zobraz pomoc k príkazom"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Použi '.help <cmd>' aby si získal viac informácií, alebo '.help all' pre "
+"zobrazenie všetkého."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<nie je k dispozícií>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Chyba v lua skripte:"
@@ -307,6 +300,10 @@ msgstr "Inštaluj $1"
 msgid "Install missing dependencies"
 msgstr "Nainštaluj chýbajúce závislosti"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Inštalácia: Nepodporovaný typ súboru, alebo poškodený archív"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -638,7 +635,7 @@ msgid "Offset"
 msgstr "Ofset"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Vytrvalosť"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -751,14 +748,6 @@ msgstr ""
 "Inštalácia rozšírenia: Nie je možné nájsť vhodný adresár pre balíček "
 "rozšírení $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Inštalácia: Nepodporovaný typ súboru \"$1\", alebo poškodený archív"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Inštalácia: súbor: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Nie je možné nájsť platné rozšírenie, alebo balíček rozšírení"
@@ -795,16 +784,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "O"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Aktívny prispievatelia"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Zasielaný rozsah aktívnych objektov"
+msgstr "Aktívny renderer:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -939,9 +927,8 @@ msgid "Start Game"
 msgstr "Spusti hru"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adresa: "
+msgstr "Adresa"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -957,22 +944,20 @@ msgstr "Kreatívny mód"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Zranenie"
+msgstr "Zranenie / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Zmaž obľúbené"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "Obľúbené"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Nekompatibilné servery"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -983,16 +968,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Zverejni server"
+msgstr "Verejné servery"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Obnov"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Popis servera"
 
@@ -1037,13 +1020,12 @@ msgid "Connected Glass"
 msgstr "Prepojené sklo"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Tieň písma"
+msgstr "Dynamické tiene"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dynamické tiene: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1051,15 +1033,15 @@ msgstr "Ozdobné listy"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Vysoké"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Nízke"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Stredné"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1133,10 +1115,6 @@ msgstr "Jemné osvetlenie"
 msgid "Texturing:"
 msgstr "Textúrovanie:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Aby mohli byť aktivované shadery, musí sa použiť OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Optim. farieb"
@@ -1151,11 +1129,11 @@ msgstr "Trilineárny filter"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Veľmi vysoké"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Veľmi nízke"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1169,7 +1147,7 @@ msgstr "Vlniace sa kvapaliny"
 msgid "Waving Plants"
 msgstr "Vlniace sa rastliny"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Časový limit pripojenia vypršal."
 
@@ -1198,8 +1176,8 @@ msgid "Connection error (timed out?)"
 msgstr "Chyba spojenia (časový limit?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Nie je možné nájsť alebo nahrať hru \""
+msgid "Could not find or load game"
+msgstr "Nie je možné nájsť alebo nahrať hru"
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1241,14 +1219,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adresa: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Kreatívny mód: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Poškodenie: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Mode: "
@@ -1270,6 +1240,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- Meno servera: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Chyba pri serializácií:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Prístup zamietnutý. Dôvod: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Automatický pohyb vpred je zakázaný"
@@ -1278,6 +1257,22 @@ msgstr "Automatický pohyb vpred je zakázaný"
 msgid "Automatic forward enabled"
 msgstr "Automatický pohyb vpred je aktivovaný"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Hranice bloku sú skryté"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Hranice bloku sú zobrazené pre všetky bloky"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Hranice bloku sú zobrazené pre aktuálny blok"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Hranice bloku sú zobrazené pre blízke bloky"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Aktualizácia kamery je zakázaná"
@@ -1286,6 +1281,11 @@ msgstr "Aktualizácia kamery je zakázaná"
 msgid "Camera update enabled"
 msgstr "Aktualizácia kamery je aktivovaná"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+"Hranice bloku nie je možné zobraziť (je potrebné oprávnenie 'basic_debug')"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Zmeniť heslo"
@@ -1298,6 +1298,10 @@ msgstr "Filmový režim je zakázaný"
 msgid "Cinematic mode enabled"
 msgstr "Filmový režim je aktivovaný"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Klient je odpojený"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Skriptovanie na strane klienta je zakázané"
@@ -1306,6 +1310,10 @@ msgstr "Skriptovanie na strane klienta je zakázané"
 msgid "Connecting to server..."
 msgstr "Pripájam sa k serveru..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Spojenie sa z neznámeho dôvodu nepodarilo"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Pokračuj"
@@ -1343,6 +1351,11 @@ msgstr ""
 "- Myš koliesko: zvoľ si vec\n"
 "- %s: komunikácia\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Nepodarilo za vyhodnotiť adresu: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Vytváram klienta..."
@@ -1472,9 +1485,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Minimapa je aktuálne zakázaná hrou, alebo rozšírením"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Hra pre jedného hráča"
+msgstr "Hra pre viacerých hráčov"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1549,6 +1561,21 @@ msgstr "Zvukový systém nie je podporovaný v tomto zostavení"
 msgid "Sound unmuted"
 msgstr "Zvuk je obnovený"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Na serveri pravdepodobne beží iná verzia %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Nemôžem sa pripojiť na %s, lebo IPv6 je zakázané"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Nemôžem sa spojiť s %s, lebo IPv6 je zakázané"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1883,6 +1910,14 @@ msgstr "Minimapa v povrchovom režime, priblíženie x%d"
 msgid "Minimap in texture mode"
 msgstr "Minimapa v móde textúry"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Nepodarilo sa otvoriť web stránku"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Otváram web stránku"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Hesla sa nezhodujú!"
@@ -1911,9 +1946,8 @@ msgid "Proceed"
 msgstr "Pokračuj"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Špeciál\"=šplhaj dole"
+msgstr "\"Aux1\"=šplhaj dole"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1925,7 +1959,7 @@ msgstr "Automatické skákanie"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1933,7 +1967,7 @@ msgstr "Vzad"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Hranice bloku"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2086,8 +2120,9 @@ msgid "Muted"
 msgstr "Zvuk stlmený"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Hlasitosť: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Hlasitosť: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2111,14 +2146,13 @@ msgstr ""
 "Ak je vypnuté, virtuálny joystick sa vycentruje na pozícií prvého dotyku."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Použije virtuálny joystick na stlačenie tlačidla \"aux\".\n"
-"Ak je aktivované, virtuálny joystick stlačí tlačidlo \"aux\" keď je mimo "
+"(Android) Použije virtuálny joystick na stlačenie tlačidla \"Aux1\".\n"
+"Ak je aktivované, virtuálny joystick stlačí tlačidlo \"Aux1\" keď je mimo "
 "hlavný kruh."
 
 #: src/settings_translation_file.cpp
@@ -2339,6 +2373,12 @@ msgstr ""
 "Nastav dpi konfiguráciu podľa svojej obrazovky (nie pre X11/len pre Android) "
 "napr. pre 4k obrazovky."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Uprav zistenú hustotu zobrazenia, použitú pre zmenu veľkosti prvkov "
+"grafického rozhrania."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2474,14 +2514,12 @@ msgid "Autoscaling mode"
 msgstr "Režim automatickej zmeny mierky"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Tlačidlo Skok"
+msgstr "Tlačidlo Aux1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Špeciálna klávesa pre šplhanie hore/dole"
+msgstr "Klávesa Aux1 pre šplhanie hore/dole"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2632,9 +2670,12 @@ msgstr ""
 "Kde 0.0 je minimálna úroveň, 1.0 je maximálna úroveň ."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Hranica správ pre vylúčenie"
+msgstr "Časové obmedzenie príkazu v správe"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Komunikačné príkazy"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2669,8 +2710,8 @@ msgid "Chat toggle key"
 msgstr "Tlačidlo Prepnutie komunikácie"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "KomunikaÄ\8d© príkazy"
+msgid "Chat weblinks"
+msgstr "KomunikaÄ\8d¡ webové odkazy"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2688,6 +2729,14 @@ msgstr "Tlačidlo Filmový režim"
 msgid "Clean transparent textures"
 msgstr "Vyčisti priehľadné textúry"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Spustiteľné webové odkazy (kliknutie stredným tlačítkom, alebo CTRL+ľave "
+"kliknutie) sú v komunikačnej konzole povolené."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klient"
@@ -2733,9 +2782,8 @@ msgid "Colored fog"
 msgstr "Farebná hmla"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Farebná hmla"
+msgstr "Farebné tiene"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2776,6 +2824,30 @@ msgstr ""
 msgid "Command key"
 msgstr "Tlačidlo Príkaz"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Úroveň kompresie použitej pri ukladaní blokov mapy na disk.\n"
+"-1 - predvolená úroveň kompresie\n"
+"0 - najmenšia kompresia, najrýchlejšie\n"
+"9 - najlepšia kompresia, najpomalšie"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Úroveň kompresie použitej pri posielaní blokov mapy klientom.\n"
+"-1 - predvolená úroveň kompresie\n"
+"0 - najmenšia kompresia, najrýchlejšie\n"
+"9 - najlepšia kompresia, najpomalšie"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Prepojené sklo"
@@ -2876,10 +2948,10 @@ msgstr "Priehľadnosť zameriavača"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Priehľadnosť zameriavača (nepriehľadnosť, medzi 0 a 255).\n"
-"Tiež nastavuje farbu objektu zameriavača"
+"Tiež nastavuje farbu objektu zameriavača."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2959,10 +3031,13 @@ msgstr "Štandardná veľkosť kôpky"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Definuje kvalitu filtrovania tieňov\n"
+"Toto simuluje efekt jemných tieňov použitím PCF alebo poisson disk\n"
+"zároveň ale spotrebováva viac zdrojov."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3086,6 +3161,10 @@ msgstr "Zakáž anticheat"
 msgid "Disallow empty passwords"
 msgstr "Zakáž prázdne heslá"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Faktor škálovania hustoty zobrazenia"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Doménové meno servera, ktoré bude zobrazené v zozname serverov."
@@ -3136,9 +3215,21 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Aktivuj poisson disk filtrovanie.\n"
+"Ak je aktivované použije poisson disk pre vytvorenie \"mäkkých tieňov\". V "
+"opačnom prípade sa použije PCF filtrovanie."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Aktivuje farebné tiene.\n"
+"Ak je aktivovaný, tak priesvitné kocky dávajú farebné tiene. Toto je náročné."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3164,13 +3255,6 @@ msgstr "Aktivuj rozšírenie pre zabezpečenie"
 msgid "Enable players getting damage and dying."
 msgstr "Aktivuje aby mohol byť hráč zranený a zomrieť."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Aktivuje náhodný užívateľský vstup (používa sa len pre testovanie)."
@@ -3281,6 +3365,14 @@ msgstr ""
 "a ovládanie hlasitosti v hre bude nefunkčné.\n"
 "Zmena tohto nastavenia si vyžaduje reštart hry."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+"Povolí kompromis, ktorý zníži zaťaženie CPU, alebo zvýši výkon renderovania\n"
+"za cenu drobných vizuálnych chýb, ktoré neovplyvnia hrateľnosť."
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Interval tlače profilových dát enginu"
@@ -3343,12 +3435,11 @@ msgid "Fast movement"
 msgstr "Rýchly pohyb"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Rýchly pohyb (cez \"špeciálnu\" klávesu).\n"
+"Rýchly pohyb (cez \"Aux1\" klávesu).\n"
 "Toto si na serveri vyžaduje privilégium \"fast\"."
 
 #: src/settings_translation_file.cpp
@@ -3381,7 +3472,6 @@ msgid "Filmic tone mapping"
 msgstr "Filmový tone mapping"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3390,9 +3480,12 @@ msgid ""
 msgstr ""
 "Filtrované textúry môžu zmiešať svoje RGB hodnoty s plne priehľadnými "
 "susedmi,\n"
-"s PNG optimizérmi obvykle zmazané, niekdy môžu viesť k tmavým oblastiam\n"
-"alebo svetlým rohom na priehľadnej textúre.\n"
-"Aplikuj tento filter na ich vyčistenie pri nahrávaní textúry."
+"ktoré sú PNG optimizérmi obvykle zmazané, niekdy môžu viesť k tmavým "
+"oblastiam\n"
+"alebo svetlým rohom na priehľadnej textúre. Aplikuj tento filter na ich "
+"vyčistenie\n"
+"pri nahrávaní textúry. Toto je automaticky aktivované, ak je aktivovaný "
+"mipmapping."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3483,12 +3576,16 @@ msgid "Font size"
 msgstr "Veľkosť písma"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
-msgstr "Veľkosť písma štandardného písma v bodoch (pt)."
+msgid "Font size divisible by"
+msgstr "Veľkosť písma deliteľná"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr "Veľkosť písma s pevnou šírkou v bodoch (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Veľkosť písma štandardného fontu, kde 1jednotka = 1 pixel pri 96 DPI"
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Veľkosť písma s pevnou šírkou, kde 1jednotka = 1 pixel pri 96 DPI"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3499,6 +3596,24 @@ msgstr ""
 "(pt).\n"
 "Pri hodnote 0 bude použitá štandardná veľkosť písma."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+"Pre pixelové písma, ktoré sa zle škálujú, toto zabezpečí, že použité "
+"veľkosti písma\n"
+"s týmto fontom budú vždy deliteľné touto hodnotou v pixeloch. Napríklad,\n"
+"pixelové písmo vysoké 16 pixelov, by malo mať toto nastavené na 16, aby sa "
+"veľkosť\n"
+"menila len na hodnoty 16, 32, 48, atď., takže rozšírenie požadujúce veľkosť "
+"25 dostane 32."
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3567,10 +3682,6 @@ msgstr "Typ fraktálu"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Zlomok viditeľnej vzdialenosti od ktorej začne byť vykresľovaná hmla"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "FreeType písma"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3629,7 +3740,7 @@ msgstr "Globálne odozvy"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Globálne atribúty pre generovanie máp.\n"
 "V generátore v6 príznak 'decorations' riadi všetky dekorácie okrem stromov\n"
@@ -3716,10 +3827,9 @@ msgid "Heat noise"
 msgstr "Teplotný šum"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "Výška okna po spustení."
+msgstr "Výška okna po spustení. Ignorované v móde plnej obrazovky."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3972,12 +4082,12 @@ msgstr ""
 "sa bezvýznamne, bez úžitku neplytvalo výkonom CPU."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Ak je aktivované, použije sa \"špeciálna\" klávesa na lietanie, v prípade,\n"
+"Ak nie je aktivované, použije sa \"Aux1\" klávesa na rýchle lietanie, v "
+"prípade,\n"
 "že je povolený režim lietania aj rýchlosti."
 
 #: src/settings_translation_file.cpp
@@ -4005,14 +4115,13 @@ msgstr ""
 "Toto si na serveri vyžaduje privilégium \"noclip\"."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Ak je aktivované, použije sa namiesto klávesy pre \"zakrádanie\" \"špeciálnu "
-"klávesu\"\n"
+"Ak je aktivované, použije sa namiesto klávesy pre \"zakrádanie\" \"Aux1\" "
+"klávesu\n"
 "pre klesanie a šplhanie dole."
 
 #: src/settings_translation_file.cpp
@@ -4072,6 +4181,8 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Ak vykonanie príkazu trvá dlhšie ako zadaný čas v sekundách,\n"
+"tak pridá informáciu o čase do komunikačného správy príkazu"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4126,7 +4237,7 @@ msgstr ""
 "Toto je obvykle potrebné len pre core/builtin prispievateľov"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr "Inštrumentuj komunikačné príkazy pri registrácií."
 
 #: src/settings_translation_file.cpp
@@ -4216,7 +4327,7 @@ msgid "Joystick button repetition interval"
 msgstr "Interval opakovania tlačidla joysticku"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Mŕtva zóna joysticku"
 
 #: src/settings_translation_file.cpp
@@ -5332,9 +5443,8 @@ msgid "Map save interval"
 msgstr "Interval ukladania mapy"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
-msgid "Map update time"
-msgstr "Aktualizačný interval tekutín"
+msgid "Map shadows update frames"
+msgstr "Aktualizačný čas mapy tieňov"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5447,7 +5557,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Maximálna vzdialenosť pre renderovanie tieňov."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5578,7 +5688,6 @@ msgstr ""
 "0 pre zakázanie fronty a -1 pre neobmedzenú frontu."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
@@ -5591,6 +5700,8 @@ msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Maximálny čas v ms, ktorý môže zabrať interaktívna požiadavka (napr. "
+"sťahovanie zoznamu serverov)."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5655,7 +5766,7 @@ msgid "Mod channels"
 msgstr "Komunikačné kanály rozšírení"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr "Upraví veľkosť elementov v užívateľskom rozhraní."
 
 #: src/settings_translation_file.cpp
@@ -5666,6 +5777,10 @@ msgstr "Cesta k písmu s pevnou šírkou"
 msgid "Monospace font size"
 msgstr "Veľkosť písmo s pevnou šírkou"
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr "Veľkosť písma s pevnou šírkou deliteľná"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Šum pre výšku hôr"
@@ -5809,11 +5924,11 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Počet extra blokov, ktoré môžu byť naraz nahrané pomocou /clearobjects.\n"
-"Toto je kompromis medzi vyťažením sqlite transakciami\n"
+"Toto je kompromis medzi vyťažením SQLite transakciami\n"
 "a spotrebou pamäti (4096=100MB, ako približné pravidlo)."
 
 #: src/settings_translation_file.cpp
@@ -5838,18 +5953,17 @@ msgstr ""
 "Otvorí menu pozastavenia, ak aktuálne okno hry nie je vybrané.\n"
 "Nepozastaví sa ak je otvorený formspec."
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "Voliteľná zmena farby webového odkazu v komunikačnej konzole."
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
-"Cesta k záložnému písmu.\n"
-"Ak je aktívne nastavenie “freetype”: Musí to byť TrueType písmo.\n"
-"Ak je zakázané nastavenie “freetype”: Musí to byť bitmapové, alebo XML "
-"vektorové písmo.\n"
+"Cesta k záložnému písmu. Musí to byť TrueType font.\n"
 "Toto písmo bude použité pre určité jazyky, alebo ak nie je štandardné písmo "
 "k dispozícií."
 
@@ -5876,28 +5990,18 @@ msgstr "Cesta do adresára s textúrami. Všetky textúry sú najprv hľadané t
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
-"Cesta k štandardnému písmu.\n"
-"Ak je aktivné nastavenie “freetype”: Musí to byť TrueType písmo.\n"
-"Ak je zakázané nastavenie “freetype”: Musí to byť bitmapové, alebo XML "
-"vektorové písmo.\n"
+"Cesta k štandardnému písmu. Musí to byť TrueType font.\n"
 "Bude použité záložné písmo, ak nebude možné písmo nahrať."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
-"Cesta k písmu s pevnou šírkou.\n"
-"Ak je aktívne nastavenie “freetype”: Musí to byť TrueType písmo.\n"
-"Ak je zakázané nastavenie “freetype”: Musí to byť bitmapové, alebo XML "
-"vektorové písmo.\n"
+"Cesta k písmu s pevnou šírkou. Musí to byť TrueType font.\n"
 "Toto písmo je použité pre napr. konzolu a okno profilera."
 
 #: src/settings_translation_file.cpp
@@ -5953,9 +6057,8 @@ msgid "Player versus player"
 msgstr "Hráč proti hráčovi (PvP)"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Bilineárne filtrovanie"
+msgstr "Poisson filtrovanie"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6010,12 +6113,12 @@ msgstr "Odpočúvacia adresa Promethea"
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Odpočúvacia adresa Promethea.\n"
-"Ak je minetest skompilovaný s nastaveným ENABLE_PROMETHEUS,\n"
+"Ak je Minetest skompilovaný s nastaveným ENABLE_PROMETHEUS,\n"
 "aktivuj odpočúvanie metriky pre Prometheus na zadanej adrese.\n"
 "Metrika môže byť získaná na http://127.0.0.1:30000/metrics"
 
@@ -6351,36 +6454,36 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
+"Nastav silu tieňov.\n"
+"Nižšia hodnota znamená svetlejšie tiene, vyššia hodnota znamená tmavšie "
+"tiene."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Nastav dosah mäkkých tieňov.\n"
+"Nižšia hodnota znamená ostrejšie a vyššia jemnejšie tiene.\n"
+"Minimálna hodnota: 1.0; max. hodnota: 10.0"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Nastav sklon orbity slnka/mesiaca v stupňoch\n"
+"Hodnota 0 znamená bez vertikálneho sklonu orbity.\n"
+"Minimálna hodnota: 0.0; max. hodnota: 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Nastav true pre povolenie vlniacich sa listov.\n"
+"Nastav true pre povolenie mapovania tieňov.\n"
 "Požaduje aby boli aktivované shadery."
 
 #: src/settings_translation_file.cpp
@@ -6413,6 +6516,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Nastav kvalitu textúr tieňov na 32 bitov.\n"
+"Ak je false, použijú sa 16 bitové textúry.\n"
+"Toto môže spôsobiť v tieňoch viac artefaktov."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6431,22 +6537,21 @@ msgstr ""
 "Toto funguje len s OpenGL."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Kvalita snímok obrazovky"
+msgstr "Kvalita filtra pre tiene"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
 msgstr ""
+"Maximálna vzdialenosť v kockách, pre mapu tieňov na renderovanie tieňov"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "32 bitové textúry pre mapovanie tieňov"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Minimálna veľkosť textúry"
+msgstr "Veľkosť textúry pre mapovanie tieňov"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6458,7 +6563,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Sila tieňov"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6481,8 +6586,8 @@ msgstr ""
 "Po zmene je požadovaný reštart."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
-msgstr "Pri mene zobraz štandardne pozadie"
+msgid "Show name tag backgrounds by default"
+msgstr "Štandardne zobraz menovku pozadia"
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
@@ -6517,7 +6622,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Sklon orbity na oblohe"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6577,9 +6682,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Rýchlosť zakrádania sa, v kockách za sekundu."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Priehľadnosť tieňa písma"
+msgstr "Dosah mäkkých tieňov"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6607,6 +6711,18 @@ msgstr ""
 "Ber v úvahu, že rozšírenia, alebo hry môžu explicitne nastaviť veľkosť pre "
 "určité (alebo všetky) typy."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"Rozptýľ celkovú aktualizáciu mapy tieňov cez zadané množstvo snímok.\n"
+"Vyššie hodnoty môžu spôsobiť trhanie tieňov, nižšie hodnoty\n"
+"spotrebujú viac zdrojov.\n"
+"Minimálna hodnota: 1; maximálna hodnota: 16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6742,8 +6858,11 @@ msgstr "Cesta k textúram"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Veľkosť textúry pre renderovanie mapy tieňov.\n"
+"Toto musí byť mocnina dvoch.\n"
+"Väčšie čísla vytvoria lepšie tiene, ale sú aj náročnejšie."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6766,7 +6885,7 @@ msgid "The URL for the content repository"
 msgstr "Webová adresa (URL) k úložisku doplnkov"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "Mŕtva zóna joysticku"
 
 #: src/settings_translation_file.cpp
@@ -6841,7 +6960,6 @@ msgstr ""
 "Malo by to byť konfigurované spolu s active_object_send_range_blocks."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6850,7 +6968,7 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Renderovací back-end pre Irrlicht.\n"
+"Renderovací back-end.\n"
 "Po zmene je vyžadovaný reštart.\n"
 "Poznámka: Na Androide, ak si nie si istý, ponechaj OGLES1! Aplikácia by "
 "nemusela naštartovať.\n"
@@ -6860,7 +6978,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Citlivosť osí joysticku pre pohyb\n"
 "otáčania pohľadu v hre."
@@ -6977,6 +7095,10 @@ msgstr "Oneskorenie popisku"
 msgid "Touch screen threshold"
 msgstr "Prah citlivosti dotykovej obrazovky"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "Kompromisy za výkon"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Šum stromov"
@@ -7055,12 +7177,12 @@ msgstr "Použi bilineárne filtrovanie pri zmene mierky textúr."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
-"Použi mip mapy pre úpravu textúr. Môže jemne zvýšiť výkon,\n"
-"obzvlášť použití balíčka textúr s vysokým rozlíšením.\n"
+"Použi mip mapy pre zmenu veľkosti textúr. Môže jemne zvýšiť výkon,\n"
+"obzvlášť pri použití balíčka textúr s vysokým rozlíšením.\n"
 "Gama korektné podvzorkovanie nie je podporované."
 
 #: src/settings_translation_file.cpp
@@ -7182,9 +7304,8 @@ msgid "Viewing range"
 msgstr "Vzdialenosť dohľadu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Virtuálny joystick stlačí tlačidlo aux"
+msgstr "Virtuálny joystick aktivuje tlačidlo Aux1"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7261,6 +7382,10 @@ msgstr "Vlnová dĺžka vlniacich sa tekutín"
 msgid "Waving plants"
 msgstr "Vlniace sa rastliny"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Farba webového odkazu"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7284,13 +7409,12 @@ msgstr ""
 "nepodporujú sťahovanie textúr z hardvéru."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7301,27 +7425,17 @@ msgstr ""
 "s najbližším susedom aby bola zachovaná ostrosť pixelov.\n"
 "Toto nastaví minimálnu veľkosť pre upravenú textúru;\n"
 "vyššia hodnota znamená ostrejší vzhľad, ale potrebuje viac pamäti.\n"
-"Odporúčané sú mocniny 2. Nastavenie viac než 1 nemusí mať viditeľný efekt,\n"
-"kým nie je použité  bilineárne/trilineárne/anisotropné filtrovanie.\n"
+"Odporúčané sú mocniny 2. Nastavenie sa aplikuje len,\n"
+"ak je použité bilineárne/trilineárne/anisotropné filtrovanie.\n"
 "Toto sa tiež používa ako základná veľkosť textúry kociek pre\n"
 "\"world-aligned autoscaling\" textúr."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Aby boli FreeType písma použité, je nutné aby bola podpora FreeType "
-"zakompilovaná.\n"
-"Ak je zakázané, budú použité bitmapové a XML vektorové písma."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
-"Či sa má pri mene zobraziť pozadie.\n"
+"Či sa má štandardne zobraziť menovka pozadia.\n"
 "Rozšírenia stále môžu pozadie nastaviť."
 
 #: src/settings_translation_file.cpp
@@ -7370,9 +7484,8 @@ msgid ""
 msgstr "Zobrazenie ladiaceho okna na klientovi (má rovnaký efekt ako F5)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "Šírka okna po spustení."
+msgstr "Šírka okna po spustení. Ignorované v móde celej obrazovky."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7473,49 +7586,24 @@ msgstr "Y-úroveň dolnej časti terénu a morského dna."
 msgid "Y-level of seabed."
 msgstr "Y-úroveň morského dna."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Úroveň kompresie ZLib používaný pri ukladaní blokov mapy na disk.\n"
-"-1 - predvolená úroveň kompresie Zlib\n"
-"0 - bez kompresie, najrýchlejšie\n"
-"9 - najlepšia kompresia, najpomalšie\n"
-"(pre úrovne 1-3 používa Zlib \"rýchlu\" metódu, pre 4-9 používa normálnu "
-"metódu)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Úroveň kompresie ZLib používaný pri posielaní blokov mapy klientom.\n"
-"-1 - predvolená úroveň kompresie Zlib\n"
-"0 - bez kompresie, najrýchlejšie\n"
-"9 - najlepšia kompresia, najpomalšie\n"
-"(pre úrovne 1-3 používa Zlib \"rýchlu\" metódu, pre 4-9 používa normálnu "
-"metódu)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL časový rámec sťahovania súborov"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "Časový rámec cURL"
+msgstr "Časový rámec interakcie cURL"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "Paralelný limit cURL"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kreatívny mód: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Poškodenie: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7628,6 +7716,9 @@ msgstr "Paralelný limit cURL"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Veľkosť písma záložného písma v bodoch (pt)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType písma"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP v režime celej obrazovky"
 
@@ -7640,6 +7731,9 @@ msgstr "Paralelný limit cURL"
 #~ msgid "High-precision FPU"
 #~ msgstr "Vysoko-presné FPU"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Inštalácia: súbor: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "Hlavné"
 
@@ -7714,6 +7808,17 @@ msgstr "Paralelný limit cURL"
 #~ msgid "Reset singleplayer world"
 #~ msgstr "Vynuluj svet jedného hráča"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "Nastav aktualizačný čas tieňov.\n"
+#~ "Nižšia hodnota znamená. že sa mapa a tiene aktualizujú rýchlejšie, ale "
+#~ "spotrebuje sa viac zdrojov.\n"
+#~ "Minimálna hodnota je 0.001 sekúnd max. hodnota je 0.2 sekundy"
+
 #~ msgid ""
 #~ "Shadow offset (in pixels) of the fallback font. If 0, then shadow will "
 #~ "not be drawn."
@@ -7733,11 +7838,26 @@ msgstr "Paralelný limit cURL"
 #~ msgid "Strength of generated normalmaps."
 #~ msgstr "Intenzita generovaných normálových máp."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Aby mohli byť aktivované shadery, musí sa použiť OpenGL."
+
 #~ msgid "View"
 #~ msgstr "Zobraziť"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Aby boli FreeType písma použité, je nutné aby bola podpora FreeType "
+#~ "zakompilovaná.\n"
+#~ "Ak je zakázané, budú použité bitmapové a XML vektorové písma."
+
 #~ msgid "Yes"
 #~ msgstr "Áno"
 
+#~ msgid "You died."
+#~ msgstr "Zomrel si."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index c39836dd0c5190c8fae5d36194086f74aace7e7c..cab8e9dae50afc2e90794c907299f904f72637b7 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Slovenian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2020-09-30 19:41+0000\n"
 "Last-Translator: Iztok Bajcar <iztok.bajcar@gmail.com>\n"
 "Language-Team: Slovenian <https://hosted.weblate.org/projects/minetest/"
@@ -63,11 +63,6 @@ msgstr "Ponovno oživi"
 msgid "You died"
 msgstr "Umrl si"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Umrl si"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -99,6 +94,10 @@ msgstr ""
 msgid "OK"
 msgstr "V redu"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Prišlo je do napake v Lua skripti:"
@@ -308,6 +307,11 @@ msgstr "Namesti"
 msgid "Install missing dependencies"
 msgstr "Izbirne možnosti:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Nameščanje: nepodprta vrsta datoteke \"$1\" oziroma okvarjen arhiv"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -652,7 +656,8 @@ msgid "Offset"
 msgstr "Odmik"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "Trajanje"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -765,14 +770,6 @@ msgstr ""
 "Namestitev prilagoditve: ni mogoče najti ustreznega imena mape za paket "
 "prilagoditev $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Nameščanje: nepodprta vrsta datoteke \"$1\" oziroma okvarjen arhiv"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Namesti: datoteka: »$1«"
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Ni mogoče najti ustrezne prilagoditve ali paketa prilagoditev"
@@ -1149,10 +1146,6 @@ msgstr "Gladko osvetljevanje"
 msgid "Texturing:"
 msgstr "Tekstura:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Za prikaz senčenja mora biti omogočen gonilnik OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Barvno preslikavanje"
@@ -1186,7 +1179,7 @@ msgstr "Valovanje tekočin"
 msgid "Waving Plants"
 msgstr "Pokaži nihanje rastlin"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Povezava je potekla."
 
@@ -1215,7 +1208,8 @@ msgid "Connection error (timed out?)"
 msgstr "Napaka povezave (ali je dejanje časovno preteklo?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Ni mogoče najti oziroma naložiti igre »"
 
 #: src/client/clientlauncher.cpp
@@ -1260,14 +1254,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "– Naslov: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "– Ustvarjalni način: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "– Poškodbe: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "– Način: "
@@ -1289,6 +1275,16 @@ msgstr "– Igra PvP: "
 msgid "- Server Name: "
 msgstr "– Ime strežnika: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Prišlo je do napake:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Samodejno premikanje naprej je onemogočeno"
@@ -1297,6 +1293,22 @@ msgstr "Samodejno premikanje naprej je onemogočeno"
 msgid "Automatic forward enabled"
 msgstr "Samodejno premikanje naprej je omogočeno"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Posodabljanje kamere je onemogočeno"
@@ -1305,6 +1317,10 @@ msgstr "Posodabljanje kamere je onemogočeno"
 msgid "Camera update enabled"
 msgstr "Posodabljanje kamere je omogočeno"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Spremeni geslo"
@@ -1317,6 +1333,10 @@ msgstr "Filmski način(Cinematic mode) je onemogočen"
 msgid "Cinematic mode enabled"
 msgstr "Filmski način (Cinematic mode) je omogočen"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Skriptiranje s strani odjemalca je onemogočeno"
@@ -1325,6 +1345,10 @@ msgstr "Skriptiranje s strani odjemalca je onemogočeno"
 msgid "Connecting to server..."
 msgstr "Poteka povezovanje s strežnikom ..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Nadaljuj"
@@ -1362,6 +1386,11 @@ msgstr ""
 "- kolesce miške: izbere orodje iz  zaloge\n"
 "- %s 9: omogoči klepet\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Ustvarjanje odjemalca ..."
@@ -1573,6 +1602,21 @@ msgstr "Zvočni sistem v tej izdaji Minetesta ni podprt"
 msgid "Sound unmuted"
 msgstr "Zvok ni utišan"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1916,6 +1960,15 @@ msgstr "Zemljevid (minimap) je v načinu prikazovanja površja, Zoom x1"
 msgid "Minimap in texture mode"
 msgstr "Zemljevid (minimap) je v načinu prikazovanja površja, Zoom x1"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Prenos $1 je spodletel"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Gesli se ne ujemata!"
@@ -2120,7 +2173,8 @@ msgid "Muted"
 msgstr "Utišano"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Glasnost zvoka: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2371,6 +2425,10 @@ msgstr ""
 "Nastavite dpi konfiguracijo (gostoto prikaza) svojemu ekranu (samo za ne-X11/"
 "Android), npr. za 4K ekrane."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2669,6 +2727,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Ukaz"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2705,8 +2768,9 @@ msgid "Chat toggle key"
 msgstr "Tipka za preklop na klepet"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "Pogovor je prikazan"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -2726,6 +2790,12 @@ msgstr "Tipka za filmski način"
 msgid "Clean transparent textures"
 msgstr "Čiste prosojne teksture"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Odjemalec"
@@ -2802,6 +2872,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Tipka Command"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Poveži steklo"
@@ -2896,7 +2982,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2976,8 +3062,8 @@ msgstr "Privzeta igra"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3099,6 +3185,10 @@ msgstr "Onemogoči preprečevanje goljufanja"
 msgid "Disallow empty passwords"
 msgstr "Ne dovoli praznih gesel"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Ime domene strežnika, ki se prikaže na seznamu strežnikov."
@@ -3145,7 +3235,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3174,13 +3271,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr "Omogoči, da igralci dobijo poškodbo in umrejo."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3265,6 +3355,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3457,11 +3553,15 @@ msgid "Font size"
 msgstr "Velikost pisave"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3470,6 +3570,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3532,10 +3643,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3584,7 +3691,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4035,7 +4142,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4120,7 +4227,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4949,7 +5056,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5243,7 +5350,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5254,6 +5361,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5375,7 +5486,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5399,11 +5510,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5426,17 +5539,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5543,9 +5652,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5839,26 +5948,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5949,7 +6050,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6061,6 +6162,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6171,7 +6280,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6189,7 +6298,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6258,7 +6367,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6351,6 +6460,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6421,7 +6534,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6608,6 +6721,10 @@ msgstr "Pokaži valovanje vode"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6629,7 +6746,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6637,14 +6754,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6770,24 +6880,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6800,6 +6892,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "– Ustvarjalni način: "
+
+#~ msgid "- Damage: "
+#~ msgstr "– Poškodbe: "
+
 #, fuzzy
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
@@ -6873,6 +6971,9 @@ msgstr ""
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 podpora."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Namesti: datoteka: »$1«"
+
 #~ msgid "Main"
 #~ msgstr "Glavni"
 
@@ -6928,6 +7029,9 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Zaženi samostojno igro"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Za prikaz senčenja mora biti omogočen gonilnik OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Preklopi gladek pogled"
 
@@ -6938,5 +7042,9 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "Da"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Umrl si"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 9ce81bbae28c2c4352771d9cce95035bbf03c325..1c590fb9d7cf033351ee4f77394829f4a8c0d6df 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Serbian (cyrillic) (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2020-07-08 20:47+0000\n"
-"Last-Translator: sfan5 <sfan5@live.de>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-07-20 14:34+0000\n"
+"Last-Translator: Stefan Vukanovic <lisacvukhome@gmail.com>\n"
 "Language-Team: Serbian (cyrillic) <https://hosted.weblate.org/projects/"
 "minetest/minetest/sr_Cyrl/>\n"
 "Language: sr_Cyrl\n"
@@ -13,7 +13,7 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.7.2-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
@@ -32,29 +32,28 @@ msgstr "Изађи у мени"
 #: builtin/client/chatcommands.lua
 #, fuzzy
 msgid "Invalid command: "
-msgstr "Ð\9bокална ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
+msgstr "Ð\9dеважеÑ\9bа ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°: "
 
 #: builtin/client/chatcommands.lua
+#, fuzzy
 msgid "Issued command: "
-msgstr ""
+msgstr "Издата команда: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Ð\88едан Ð¸Ð³Ñ\80аÑ\87"
+msgstr "Ð\98злиÑ\81Ñ\82аÑ\98 Ð¼Ñ\80ежне Ð¸Ð³Ñ\80аÑ\87е"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Ð\88едан Ð¸Ð³Ñ\80аÑ\87"
+msgstr "Ð\9cÑ\80ежни Ð¸Ð³Ñ\80аÑ\87и: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Излазни ред са ћаскање је сада празан."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Ова команда није дозвољена од стране сервера."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -65,46 +64,45 @@ msgstr "Врати се у живот"
 msgid "You died"
 msgstr "Умро/ла си."
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Умро/ла си."
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Ð\9bокална ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
+msgstr "Ð\94оÑ\81Ñ\82Ñ\83пне ÐºÐ¾Ð¼Ð°Ð½Ð´Ðµ:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Ð\9bокална ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
+msgstr "Ð\94оÑ\81Ñ\82Ñ\83пне ÐºÐ¾Ð¼Ð°Ð½Ð´Ðµ: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Команда није доступна: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Нађите помоћ за команде"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Користите '.help <komanda>' да бисте добили више информација или '.help all' "
+"да бисте све набројали."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <команда>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
-msgstr ""
+msgstr "У реду"
 
 #: builtin/fstk/ui.lua
 #, fuzzy
+msgid "<none available>"
+msgstr "Команда није доступна: "
+
+#: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
-msgstr "Догодила се грешка у Lua скрипти, у моду:"
+msgstr "Догодила се грешка у Lua скрипти:"
 
 #: builtin/fstk/ui.lua
 #, fuzzy
@@ -156,7 +154,6 @@ msgstr "Прекини"
 
 #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "Dependencies:"
 msgstr "Зависи од:"
 
@@ -165,21 +162,18 @@ msgid "Disable all"
 msgstr "Онемогући све"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "Disable modpack"
-msgstr "Ð\9eнемогÑ\83Ñ\9bено"
+msgstr "Ð\9eнемогÑ\83Ñ\9bи Ð³Ñ\80Ñ\83пÑ\83 Ð¼Ð¾Ð´Ð¾Ð²Ð°"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Enable all"
 msgstr "Укључи све"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "Enable modpack"
-msgstr "Ð\9fÑ\80еименÑ\83Ñ\98 Ð¼Ð¾Ð´-паковаÑ\9aе:"
+msgstr "УкÑ\99Ñ\83Ñ\87и Ð³Ñ\80Ñ\83пÑ\83 Ð¼Ð¾Ð´Ð¾Ð²Ð°:"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid ""
 "Failed to enable mod \"$1\" as it contains disallowed characters. Only "
 "characters [a-z0-9_] are allowed."
@@ -189,36 +183,31 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Find More Mods"
-msgstr ""
+msgstr "Нађи још модова"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Mod:"
 msgstr "Мод:"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No (optional) dependencies"
-msgstr "Ð\9dеобавезне Ð·Ð°Ð²Ð¸Ñ\81ноÑ\81Ñ\82и:"
+msgstr "Ð\9dема (необавезниÑ\85) Ð·Ð°Ð²Ð¸Ñ\81ноÑ\81Ñ\82и"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No game description provided."
-msgstr "Ð\9dиÑ\98е Ð´Ð¾Ñ\81Ñ\82Ñ\83пан Ð¾Ð¿Ð¸Ñ\81 Ð¼Ð¾Ð´Ð°"
+msgstr "Ð\9dиÑ\98е Ð¿Ñ\80Ñ\83жен Ð¾Ð¿Ð¸Ñ\81 Ð¼Ð¾Ð´Ð°."
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No hard dependencies"
-msgstr "Нема зависности."
+msgstr "Ð\9dема Ð¾Ð±Ð°Ð²ÐµÐ·Ð½Ð¸Ñ\85 Ð·Ð°Ð²Ð¸Ñ\81ноÑ\81Ñ\82и."
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No modpack description provided."
-msgstr "Ð\9dиÑ\98е Ð´Ð¾Ñ\81Ñ\82Ñ\83пан Ð¾Ð¿Ð¸Ñ\81 Ð¼Ð¾Ð´Ð°"
+msgstr "Ð\9dиÑ\98е Ð¿Ñ\80Ñ\83жен Ð¾Ð¿Ð¸Ñ\81 Ð³Ñ\80Ñ\83пе Ð¼Ð¾Ð´Ð¾Ð²Ð°."
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No optional dependencies"
-msgstr "Ð\9dеобавезне Ð·Ð°Ð²Ð¸Ñ\81ноÑ\81Ñ\82и:"
+msgstr "Ð\9dема Ð½ÐµÐ¾Ð±Ð°Ð²ÐµÐ·Ð½Ð¸Ñ\85 Ð·Ð°Ð²Ð¸Ñ\81ноÑ\81Ñ\82и"
 
 #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua
 msgid "Optional dependencies:"
@@ -239,67 +228,64 @@ msgstr "укључено"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "\"$1\" already exists. Would you like to overwrite it?"
-msgstr ""
+msgstr "\"$1\" већ постоји. Да ли желите да га препишете?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
-msgstr ""
+msgstr "$1 и $2 зависности ће бити инсталиране."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1 од $2"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
 "$1 downloading,\n"
 "$2 queued"
 msgstr ""
+"$1 се преузима,\n"
+"$2 чекају преузимање"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "$1 downloading..."
-msgstr "Учитавање..."
+msgstr "$1 се преузима..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr ""
+msgstr "$1 неопходних зависности није могло бити нађено."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
-msgstr ""
+msgstr "$1 зависности ће бити инсталирано, и $2 зависности ће бити прескочено."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "All packages"
-msgstr ""
+msgstr "Сви пакети"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Already installed"
-msgstr "Ð\94Ñ\83гме Ñ\81е Ð²ÐµÑ\9b ÐºÐ¾Ñ\80иÑ\81Ñ\82и"
+msgstr "Ð\92еÑ\9b Ð¸Ð½Ñ\81Ñ\82алиÑ\80ано"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Back to Main Menu"
-msgstr "Ð\93лавни мени"
+msgstr "Ð\9dазад Ñ\83 Ð³лавни мени"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Base Game:"
-msgstr "Ð\9dапÑ\80ави Ð¸Ð³Ñ\80Ñ\83"
+msgstr "Ð\9eÑ\81новна Ð¸Ð³Ñ\80а:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
 msgstr ""
+"ContentDB није доступан када је Minetest компајлиран без cURL библиотеке"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Downloading..."
-msgstr "УÑ\87иÑ\82авање..."
+msgstr "Ð\9fÑ\80еÑ\83зимање..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Failed to download $1"
-msgstr "Ð\9dеÑ\83Ñ\81пела Ð¸Ð½Ñ\81Ñ\82алаÑ\86иÑ\98а $1 Ñ\83 $2"
+msgstr "Ð\9dеÑ\83Ñ\81пело Ð¿Ñ\80еÑ\83зимаÑ\9aе $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -311,14 +297,19 @@ msgid "Install"
 msgstr "Инсталирај"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install $1"
-msgstr "Инсталирај"
+msgstr "Инсталирај $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install missing dependencies"
-msgstr "Необавезне зависности:"
+msgstr "Инсталирај недостајуће зависности"
+
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"\n"
+"Инсталирај мод: неподржан тип фајла \"$1\" или оштећена архива"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -327,53 +318,52 @@ msgstr "Модови"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No packages could be retrieved"
-msgstr ""
+msgstr "Ниједан пакет није било могуће преузети"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No results"
-msgstr ""
+msgstr "Нема резултата"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No updates"
-msgstr ""
+msgstr "Нема ажурирања"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Not found"
-msgstr ""
+msgstr "Није пронађено"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
-msgstr ""
+msgstr "Препиши"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Please check that the base game is correct."
-msgstr ""
+msgstr "Молим проверите да ли је основна игра исправна."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "На чекању"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Texture packs"
 msgstr "Сетови текстура"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #, fuzzy
 msgid "Uninstall"
-msgstr "Ð\98нсталирај"
+msgstr "Ð\94еинсталирај"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update"
-msgstr ""
+msgstr "Ажурирај"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
-msgstr ""
+msgstr "Ажурирај све [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "Погледај још информација у веб претраживачу"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
@@ -381,70 +371,63 @@ msgstr "Свет \"$1\" већ постоји"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Additional terrain"
-msgstr ""
+msgstr "Додатни терен"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Altitude chill"
-msgstr ""
+msgstr "Висинска хладноћа"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Altitude dry"
-msgstr ""
+msgstr "Висинска сувоћа"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biome blending"
-msgstr "Семе биома"
+msgstr "СклапаÑ\9aе биома"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biomes"
-msgstr "Семе Ð±Ð¸Ð¾Ð¼Ð°"
+msgstr "Ð\91иоми"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caverns"
-msgstr "Семе Ð¿ÐµÑ\9bина"
+msgstr "Ð\9fеÑ\9bине"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caves"
-msgstr "Семе Ð¿ÐµÑ\9bина"
+msgstr "Ð\88ама"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Create"
 msgstr "Направи"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Decorations"
-msgstr "Ð\98нÑ\84оÑ\80маÑ\86иÑ\98е Ð¾ Ð¼Ð¾Ð´Ñ\83:"
+msgstr "УкÑ\80аÑ\81и"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Download a game, such as Minetest Game, from minetest.net"
 msgstr "Преузми подигру, као што је minetest_game, са minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download one from minetest.net"
-msgstr "Ð\9fÑ\80еÑ\83зми Ñ\98едан са minetest.net"
+msgstr "Ð\9fÑ\80еÑ\83зми Ñ\98еднÑ\83 са minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Dungeons"
-msgstr "Семе Ð¿ÐµÑ\9bина"
+msgstr "ТамниÑ\86е"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Flat terrain"
-msgstr ""
+msgstr "Раван терен"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floating landmasses in the sky"
-msgstr ""
+msgstr "Плутајуће копнене масе на небу"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floatlands (experimental)"
-msgstr ""
+msgstr "Floatlands (експериментални)"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Game"
@@ -452,27 +435,29 @@ msgstr "Игра"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Generate non-fractal terrain: Oceans and underground"
-msgstr ""
+msgstr "Створи нефрактални терен: Океани и подземље"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Hills"
-msgstr ""
+msgstr "Брда"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Humid rivers"
-msgstr ""
+msgstr "Влажне реке"
 
 #: builtin/mainmenu/dlg_create_world.lua
+#, fuzzy
 msgid "Increases humidity around rivers"
-msgstr ""
+msgstr "Повећава влажност око река"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Lakes"
-msgstr ""
+msgstr "Језера"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Low humidity and high heat causes shallow or dry rivers"
-msgstr ""
+msgstr "Ниска влажност и велика врућина узрокују плитке или суве реке"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen"
@@ -480,46 +465,43 @@ msgstr "Генератор мапе"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen flags"
-msgstr ""
+msgstr "Опције генератора мапа"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Mapgen-specific flags"
-msgstr "Ð\93енеÑ\80аÑ\82оÑ\80 Ð¼Ð°Ð¿Ðµ"
+msgstr "СпеÑ\86иÑ\84иÑ\87не Ð¾Ð¿Ñ\86иÑ\98е Ð³ÐµÐ½ÐµÑ\80аÑ\82оÑ\80а Ð¼Ð°Ð¿Ð°"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mountains"
-msgstr ""
+msgstr "Планине"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mud flow"
-msgstr ""
+msgstr "Проток блата"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Network of tunnels and caves"
-msgstr ""
+msgstr "Мрежа тунела и пећина"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "No game selected"
-msgstr "Ð\9eдабиÑ\80 Ð´Ð¾Ð¼ÐµÑ\82а"
+msgstr "Ð\9dиÑ\98е Ð¾Ð´Ð°Ð±Ñ\80ана Ð¸Ð³Ñ\80а"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces heat with altitude"
-msgstr ""
+msgstr "Смањује топлоту висином"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces humidity with altitude"
-msgstr ""
+msgstr "Смањује влагу висином"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Rivers"
-msgstr "Семе Ð¿ÐµÑ\9bина"
+msgstr "Реке"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Sea level rivers"
-msgstr ""
+msgstr "Реке на нивоу мора"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -528,48 +510,49 @@ msgstr "Семе"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Smooth transition between biomes"
-msgstr ""
+msgstr "Глатка транзиција између биома"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid ""
 "Structures appearing on the terrain (no effect on trees and jungle grass "
 "created by v6)"
 msgstr ""
+"Структуре које се појављују на терену (нема утицаја на дрвеће и траву џунгле "
+"коју је створила v6)"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Structures appearing on the terrain, typically trees and plants"
-msgstr ""
+msgstr "Структуре које се појављују на терену, обично дрвеће и биљке"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert"
-msgstr ""
+msgstr "Умерено, пустиња"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle"
-msgstr ""
+msgstr "Умерено, пустиња, џунгла"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr ""
+msgstr "Умерено, пустиња, џунгла, тундра, тајга"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Terrain surface erosion"
-msgstr ""
+msgstr "Ерозија површине терена"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
-msgstr ""
+msgstr "Дрвеће и трава џунгле"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Vary river depth"
-msgstr ""
+msgstr "Варирај дубину реке"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Very large caverns deep in the underground"
-msgstr ""
+msgstr "Веома велике пећине дубоко у подземљу"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Warning: The Development Test is meant for developers."
 msgstr "Упозорење: Минимални развојни тест је намењен развијачима."
 
@@ -593,14 +576,12 @@ msgid "Delete"
 msgstr "Обриши"
 
 #: builtin/mainmenu/dlg_delete_content.lua
-#, fuzzy
 msgid "pkgmgr: failed to delete \"$1\""
-msgstr "Modmgr: неуспело брисање \"$1\""
+msgstr "pkgmgr: неуспело брисање \"$1\""
 
 #: builtin/mainmenu/dlg_delete_content.lua
-#, fuzzy
 msgid "pkgmgr: invalid path \"$1\""
-msgstr "Modmgr: локација мода \"$1\" није валидна"
+msgstr "pkgmgr: локација мода \"$1\" није валидна"
 
 #: builtin/mainmenu/dlg_delete_world.lua
 msgid "Delete World \"$1\"?"
@@ -612,13 +593,15 @@ msgstr "Прихвати"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid "Rename Modpack:"
-msgstr "Ð\9fÑ\80еименÑ\83Ñ\98 Ð¼Ð¾Ð´-паковаÑ\9aе:"
+msgstr "Ð\9fÑ\80еименÑ\83Ñ\98 Ð³Ñ\80Ñ\83пÑ\83 Ð¼Ð¾Ð´Ð¾Ð²Ð°:"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid ""
 "This modpack has an explicit name given in its modpack.conf which will "
 "override any renaming here."
 msgstr ""
+"Ова група модова има специфично име дато у свом modpack.conf које ће "
+"преписати било које име дато овде."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "(No description of setting given)"
@@ -627,7 +610,7 @@ msgstr "(Није дат опис поставке)"
 #: builtin/mainmenu/dlg_settings_advanced.lua
 #, fuzzy
 msgid "2D Noise"
-msgstr "Cave2 семе"
+msgstr "2D бука"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "< Back to Settings page"
@@ -655,15 +638,16 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Octaves"
-msgstr ""
+msgstr "Октаве"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Offset"
-msgstr ""
+msgstr "Помак"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
-msgstr ""
+#, fuzzy
+msgid "Persistence"
+msgstr "Упорност"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid integer."
@@ -675,11 +659,11 @@ msgstr "Молим вас унесите валидан број."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Restore Default"
-msgstr "Поврати уобичајено"
+msgstr "Поврати подразумевано"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Scale"
-msgstr ""
+msgstr "Скала"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua
 msgid "Search"
@@ -781,18 +765,6 @@ msgstr ""
 "Инсталирај мод: не може се пронаћи одговарајуће име за фасциклу мод-паковања "
 "$1"
 
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"\n"
-"Инсталирај мод: неподржан тип фајла \"$1\" или оштећена архива"
-
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: file: \"$1\""
-msgstr "Инсталирај мод: фајл: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 #, fuzzy
 msgid "Unable to find a valid mod or modpack"
@@ -1186,10 +1158,6 @@ msgstr "Глатко осветљење"
 msgid "Texturing:"
 msgstr "Филтери за текстуре:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Да би се омогућили шејдери мора се користити OpenGL драјвер."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Тонско Мапирање"
@@ -1224,7 +1192,7 @@ msgstr "Лепршајуће лишће"
 msgid "Waving Plants"
 msgstr "Лепршајуће биљке"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Конекцији је истекло време."
 
@@ -1253,7 +1221,8 @@ msgid "Connection error (timed out?)"
 msgstr "Грешка у конекцији (истекло време?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Немогу пронаћи или учитати игру \""
 
 #: src/client/clientlauncher.cpp
@@ -1297,14 +1266,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Адреса: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Слободни мод: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Оштећење: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Мод: "
@@ -1326,6 +1287,16 @@ msgstr "- Играч против играча: "
 msgid "- Server Name: "
 msgstr "- Име сервера: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Догодила се грешка:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Automatic forward disabled"
@@ -1336,6 +1307,22 @@ msgstr "Кључ за синематски мод"
 msgid "Automatic forward enabled"
 msgstr "Кључ за синематски мод"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Camera update disabled"
@@ -1346,6 +1333,10 @@ msgstr "Кључ за укључивање/искључивање освежав
 msgid "Camera update enabled"
 msgstr "Кључ за укључивање/искључивање освежавања камере"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Промени шифру"
@@ -1360,6 +1351,11 @@ msgstr "Кључ за синематски мод"
 msgid "Cinematic mode enabled"
 msgstr "Кључ за синематски мод"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Модификовање клијента"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1368,6 +1364,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr "Повезујем се на сервер..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Настави"
@@ -1405,6 +1405,11 @@ msgstr ""
 "- Точкић миша: одабирање ставке\n"
 "- %s: причање\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Правим клијента..."
@@ -1618,6 +1623,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Јачина звука"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy, c-format
 msgid "Viewing range changed to %d"
@@ -1955,6 +1975,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Неуспело преузимање $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Шифре се не поклапају!"
@@ -2162,7 +2191,8 @@ msgid "Muted"
 msgstr "Изкључи звук"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Јачина звука: "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2394,6 +2424,10 @@ msgstr ""
 "Подеси dpi конфигурацију за твој екран (само за оне који нису X11/Android) "
 "нпр. за 4k екране."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2676,6 +2710,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Граница пећине"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Чат команде"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2713,8 +2752,8 @@ msgid "Chat toggle key"
 msgstr "Кључ за укључивање чета"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Чат команде"
+msgid "Chat weblinks"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2732,6 +2771,12 @@ msgstr "Кључ за синематски мод"
 msgid "Clean transparent textures"
 msgstr "Очисти провидне трекстуре"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Клијент"
@@ -2816,6 +2861,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Кључ за команду"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Споји стакло"
@@ -2913,7 +2974,7 @@ msgstr "Провидност нишана"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr "Провидност нишана (видљивост, између 0 и 255)."
 
 #: src/settings_translation_file.cpp
@@ -2994,8 +3055,8 @@ msgstr "Уобичајена игра"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3114,6 +3175,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -3161,7 +3226,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3189,13 +3261,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3280,6 +3345,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3468,11 +3539,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3481,6 +3556,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3540,10 +3626,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3592,7 +3674,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4028,7 +4110,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4112,7 +4194,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4942,7 +5024,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5241,7 +5323,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5252,6 +5334,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5373,7 +5459,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5397,11 +5483,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5424,17 +5512,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5542,9 +5626,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5859,26 +5943,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5970,7 +6046,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6077,6 +6153,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6187,7 +6271,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6205,7 +6289,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6274,7 +6358,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6368,6 +6452,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr "Граница семена за плаже"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6439,7 +6527,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6626,6 +6714,10 @@ msgstr "Веслајућа вода"
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6647,7 +6739,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6655,14 +6747,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6790,24 +6875,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6820,6 +6887,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Слободни мод: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Оштећење: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -6883,6 +6956,10 @@ msgstr ""
 #~ msgid "Downloading and installing $1, please wait..."
 #~ msgstr "Преузима се $1, молим вас сачекајте..."
 
+#, fuzzy
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Инсталирај мод: фајл: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "Главно"
 
@@ -6926,11 +7003,17 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Започни игру за једног играча"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Да би се омогућили шејдери мора се користити OpenGL драјвер."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Укључи/Искључи Cinematic мод"
 
 #~ msgid "Yes"
 #~ msgstr "Да"
 
+#~ msgid "You died."
+#~ msgstr "Умро/ла си."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index b5d6c235d2b8b2d7e7b4951d8c52a391911777f5..eeb7e9ce2314748022dc513414c76bde7a4c652f 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2020-08-15 23:32+0000\n"
 "Last-Translator: Milos <milosfilic97@gmail.com>\n"
 "Language-Team: Serbian (latin) <https://hosted.weblate.org/projects/minetest/"
@@ -65,11 +65,6 @@ msgstr "Vrati se u zivot"
 msgid "You died"
 msgstr "Umro/la si."
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Umro/la si."
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -99,6 +94,10 @@ msgstr ""
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Doslo je do greske u Lua skripti:"
@@ -302,6 +301,10 @@ msgstr "Instalirati"
 msgid "Install missing dependencies"
 msgstr "Neobavezne zavisnosti:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -630,7 +633,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -740,14 +743,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1115,10 +1110,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1151,7 +1142,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1180,7 +1171,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1221,14 +1212,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1250,6 +1233,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Doslo je do greske:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1258,6 +1251,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1266,6 +1275,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1278,6 +1291,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1286,6 +1303,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1309,6 +1330,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1501,6 +1527,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1835,6 +1876,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Neuspelo preuzimanje $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2030,7 +2080,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2237,6 +2288,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2503,6 +2558,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2536,7 +2595,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2555,6 +2614,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2630,6 +2695,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2721,7 +2802,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2798,8 +2879,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2917,6 +2998,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2963,7 +3048,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2991,13 +3083,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3082,6 +3167,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3266,11 +3357,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3279,6 +3374,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3338,10 +3444,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3390,7 +3492,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3822,7 +3924,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3906,7 +4008,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4735,7 +4837,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5028,7 +5130,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5039,6 +5141,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5160,7 +5266,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5184,11 +5290,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5211,17 +5319,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5324,9 +5428,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5619,26 +5723,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5729,7 +5825,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5834,6 +5930,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5944,7 +6048,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5962,7 +6066,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6031,7 +6135,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6124,6 +6228,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6194,7 +6302,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6377,6 +6485,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6398,7 +6510,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6406,14 +6518,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6539,24 +6644,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6572,5 +6659,9 @@ msgstr ""
 #~ msgid "View"
 #~ msgstr "Pogled"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Umro/la si."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 6806efea1d07ed4e031d5ae1a7a6fa73f4b3c624..9c77e9a11ccf0c87a0fe32da0939d6f7169fa03c 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Swedish (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2020-03-31 10:14+0000\n"
-"Last-Translator: sfan5 <sfan5@live.de>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2021-12-18 21:51+0000\n"
+"Last-Translator: xerxstirb <xerxstirb@gmail.com>\n"
 "Language-Team: Swedish <https://hosted.weblate.org/projects/minetest/"
 "minetest/sv/>\n"
 "Language: sv\n"
@@ -12,97 +12,90 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.10\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Rensa chattkön"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Chattkommandon"
+msgstr "Tomt kommando."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Avsluta till Meny"
+msgstr "Avsluta till huvudmeny"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Lokalt kommando"
+msgstr "Ogiltigt kommando: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Utfärdat kommando: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Enspelarläge"
+msgstr "Lista över spelare online"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Enspelarläge"
+msgstr "Spelare online: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Den utgående chattkön är nu tom."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Detta kommando är inaktiverat av servern."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
-msgstr "Återföds"
+msgstr "Återuppstå"
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "You died"
 msgstr "Du dog"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Du dog"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Lokalt kommando"
+msgstr "Tillgängliga kommandon:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Lokalt kommando"
+msgstr "Tillgängliga kommandon: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Kommando inte tillgängligt: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Få hjälp med kommandon"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Använd '.help <cmd>' för att få mer information, eller '.help all' för att "
+"visa allt."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
-msgstr ""
+msgstr "OK"
+
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<inget tillgängligt>"
 
 #: builtin/fstk/ui.lua
-#, fuzzy
 msgid "An error occurred in a Lua script:"
-msgstr "Ett fel uppstod i ett Lua-skript, såsom en mod:"
+msgstr "Ett fel uppstod i ett Lua-skript:"
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred:"
@@ -122,7 +115,7 @@ msgstr "Servern har begärt en återanslutning:"
 
 #: builtin/mainmenu/common.lua
 msgid "Protocol version mismatch. "
-msgstr "Protokollversionen matchar ej. "
+msgstr "Protokollversionen matchar inte. "
 
 #: builtin/mainmenu/common.lua
 msgid "Server enforces protocol version $1. "
@@ -158,7 +151,7 @@ msgstr "Beroenden:"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Disable all"
-msgstr "Inaktivera allt"
+msgstr "Avaktivera alla"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Disable modpack"
@@ -166,7 +159,7 @@ msgstr "Avaktivera modpaket"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Enable all"
-msgstr "Aktivera alla"
+msgstr "Aktivera allt"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Enable modpack"
@@ -182,34 +175,31 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Find More Mods"
-msgstr ""
+msgstr "Hitta Fler Moddar"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Mod:"
 msgstr "Mod:"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No (optional) dependencies"
-msgstr "Valfria beroenden:"
+msgstr "Inga (valfria) beroenden"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No game description provided."
 msgstr "Ingen spelbeskrivning tillgänglig."
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No hard dependencies"
-msgstr "Inga beroenden."
+msgstr "Inga hårda beroenden"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No modpack description provided."
 msgstr "Ingen modpaketsbeskrivning tillgänglig."
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No optional dependencies"
-msgstr "Valfria beroenden:"
+msgstr "Inga valfria beroenden"
 
 #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua
 msgid "Optional dependencies:"
@@ -230,61 +220,59 @@ msgstr "aktiverad"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "\"$1\" already exists. Would you like to overwrite it?"
-msgstr ""
+msgstr "\"$1\" finns redan. Vill du skriva över den?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
-msgstr ""
+msgstr "$1 och $2 beroende paket kommer installeras."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1 till $2"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
 "$1 downloading,\n"
 "$2 queued"
 msgstr ""
+"$1 laddas ner,\n"
+"$2 köad"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "$1 downloading..."
-msgstr "Laddar..."
+msgstr "$1 laddas ner..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr ""
+msgstr "$1 nödvändiga beroenden kunde inte hittas."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
-msgstr ""
+msgstr "$1 kommer att installeras och $2 beroenden hoppas över."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "All packages"
 msgstr "Alla paket"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Already installed"
-msgstr "Tangent används redan"
+msgstr "Redan installerad"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Back to Main Menu"
 msgstr "Tillbaka till huvudmeny"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Base Game:"
-msgstr "Bilda Spel"
+msgstr "Basspel:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
-msgstr ""
+msgstr "ContentDB är inte tillgänglig när Minetest är kompilerad utan cURL"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Downloading..."
-msgstr "Laddar..."
+msgstr "Laddar ner..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Failed to download $1"
@@ -300,14 +288,16 @@ msgid "Install"
 msgstr "Installera"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install $1"
-msgstr "Installera"
+msgstr "Installera $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install missing dependencies"
-msgstr "Valfria beroenden:"
+msgstr "Installera saknade beroenden"
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Installation: Filtyp stöds inte eller trasigt arkiv"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -323,25 +313,24 @@ msgid "No results"
 msgstr "Inga resultat"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "No updates"
-msgstr "Uppdatera"
+msgstr "Inga uppdateringar"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Not found"
-msgstr ""
+msgstr "Hittades inte"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
-msgstr ""
+msgstr "Skriv över"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Please check that the base game is correct."
-msgstr ""
+msgstr "Var snäll se att basspelet är korrekt."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "Köad"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Texture packs"
@@ -357,11 +346,11 @@ msgstr "Uppdatera"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
-msgstr ""
+msgstr "Uppdatera Alla [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "Visa mer information i en webbläsare"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
@@ -369,46 +358,39 @@ msgstr "En värld med namnet \"$1\" finns redan"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Additional terrain"
-msgstr ""
+msgstr "Ytterligare terräng"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Altitude chill"
 msgstr "Altitudkyla"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Altitude dry"
-msgstr "Altitudkyla"
+msgstr "Altitudtorka"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biome blending"
-msgstr "Biotopoljud"
+msgstr "Biotopblandning"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Biomes"
-msgstr "Biotopoljud"
+msgstr "Biotoper"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caverns"
-msgstr "Grottoljud"
+msgstr "Grottor"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Caves"
-msgstr "Oktaver"
+msgstr "Grottor"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Create"
 msgstr "Skapa"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Decorations"
-msgstr "Modinformation:"
+msgstr "Dekorationer"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download a game, such as Minetest Game, from minetest.net"
@@ -419,21 +401,20 @@ msgid "Download one from minetest.net"
 msgstr "Ladda ner ett från minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Dungeons"
-msgstr "Grottoljud"
+msgstr "Fängelsehålor"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Flat terrain"
-msgstr ""
+msgstr "Platt terräng"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floating landmasses in the sky"
-msgstr ""
+msgstr "Svävande landmassor i himlen"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floatlands (experimental)"
-msgstr ""
+msgstr "Floatlands (experimentellt)"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Game"
@@ -441,27 +422,27 @@ msgstr "Spel"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Generate non-fractal terrain: Oceans and underground"
-msgstr ""
+msgstr "Generera icke-fraktal terräng: Oceaner och underjord"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Hills"
-msgstr ""
+msgstr "Kullar"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Humid rivers"
-msgstr ""
+msgstr "Fuktiga floder"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Increases humidity around rivers"
-msgstr ""
+msgstr "Ökar luftfuktigheten runt floderna"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Lakes"
-msgstr ""
+msgstr "Sjöar"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Low humidity and high heat causes shallow or dry rivers"
-msgstr ""
+msgstr "Låg luftfuktighet och hög värme orsakar grunda eller torra floder"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen"
@@ -469,24 +450,23 @@ msgstr "Kartgenerator"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen flags"
-msgstr ""
+msgstr "Mapgen-flaggor"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Mapgen-specific flags"
-msgstr "Kartgenerator"
+msgstr "Mapgen-specifika flaggor"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mountains"
-msgstr ""
+msgstr "Berg"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mud flow"
-msgstr ""
+msgstr "Lerflöde"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Network of tunnels and caves"
-msgstr ""
+msgstr "Nätverk med tunnlar och grottor"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "No game selected"
@@ -494,20 +474,19 @@ msgstr "Inget spel valt"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces heat with altitude"
-msgstr ""
+msgstr "Minskar värmen efter höjd"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces humidity with altitude"
-msgstr ""
+msgstr "Minskar luftfuktigheten efter höjd"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Rivers"
-msgstr "Grottoljud"
+msgstr "Floder"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Sea level rivers"
-msgstr ""
+msgstr "Havsnivåfloder"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -516,50 +495,51 @@ msgstr "Frö"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Smooth transition between biomes"
-msgstr ""
+msgstr "Smidig övergång mellan biotoper"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid ""
 "Structures appearing on the terrain (no effect on trees and jungle grass "
 "created by v6)"
 msgstr ""
+"Strukturer som förekommer i terrängen (ingen effekt på träd och djungelgräs "
+"som skapats av v6)"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Structures appearing on the terrain, typically trees and plants"
-msgstr ""
+msgstr "Strukturer som förekommer i terrängen, vanligtvis träd och växter"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert"
-msgstr ""
+msgstr "Tempererad, Öken"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle"
-msgstr ""
+msgstr "Tempererad, Öken, Djungel"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr ""
+msgstr "Tempererad, Öken, Djungel, Tundra, Tajga"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Terrain surface erosion"
-msgstr ""
+msgstr "Erosion av terrängytan"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
-msgstr ""
+msgstr "Träd- och djungelgräs"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Vary river depth"
-msgstr ""
+msgstr "Varierande floddjup"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Very large caverns deep in the underground"
-msgstr ""
+msgstr "Mycket stora grottor djupt ner i underjorden"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Warning: The Development Test is meant for developers."
-msgstr "Varning: Minimala utvecklingstestet är avsett för utvecklare."
+msgstr "Varning: Utvecklingstestet är avsett för utvecklare."
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "World name"
@@ -580,14 +560,12 @@ msgid "Delete"
 msgstr "Radera"
 
 #: builtin/mainmenu/dlg_delete_content.lua
-#, fuzzy
 msgid "pkgmgr: failed to delete \"$1\""
-msgstr "Modhanterare: misslyckades radera \"$1\""
+msgstr "pkgmgr: misslyckades att radera \"$1\""
 
 #: builtin/mainmenu/dlg_delete_content.lua
-#, fuzzy
 msgid "pkgmgr: invalid path \"$1\""
-msgstr "Modhanterare: ogiltig modsökväg \"$1\""
+msgstr "pkgmgr: ogiltig sökväg \"$1\""
 
 #: builtin/mainmenu/dlg_delete_world.lua
 msgid "Delete World \"$1\"?"
@@ -606,15 +584,16 @@ msgid ""
 "This modpack has an explicit name given in its modpack.conf which will "
 "override any renaming here."
 msgstr ""
+"Detta moddpaket har ett uttryckligt namn angett i modpack.conf vilket går "
+"före namnändring här."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "(No description of setting given)"
 msgstr "(Ingen beskrivning av inställning angiven)"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-#, fuzzy
 msgid "2D Noise"
-msgstr "Grotta2 oljud"
+msgstr "2D-Brus"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "< Back to Settings page"
@@ -649,7 +628,7 @@ msgid "Offset"
 msgstr "Förskjutning"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Persistens"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -677,9 +656,8 @@ msgid "Select directory"
 msgstr "Välj katalog"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-#, fuzzy
 msgid "Select file"
-msgstr "Välj modfil:"
+msgstr "Välj fil"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Show technical names"
@@ -723,15 +701,14 @@ msgstr "Z-spridning"
 #. main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "absvalue"
-msgstr ""
+msgstr "absolutvärde"
 
 #. ~ "defaults" is a noise parameter flag.
 #. It describes the default processing options
 #. for noise settings in main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
-#, fuzzy
 msgid "defaults"
-msgstr "Standardspel"
+msgstr "standarder"
 
 #. ~ "eased" is a noise parameter flag.
 #. It is used to make the map smoother and
@@ -739,68 +716,47 @@ msgstr "Standardspel"
 #. main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "eased"
-msgstr ""
+msgstr "lättad"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "$1 (Enabled)"
-msgstr "Aktiverad"
+msgstr "$1 (Aktiverad)"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "$1 mods"
-msgstr "3D-läge"
+msgstr "$1 moddar"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Failed to install $1 to $2"
 msgstr "Misslyckades installera $1 till $2"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "Install Mod: Unable to find real mod name for: $1"
-msgstr "Modinstallation: lyckas ej hitta riktiga modnamnet för: $1"
+msgstr "Moddinstallation: Lyckades ej hitta riktiga moddnamnet för: $1"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
-msgstr "Modinstallation: lyckas ej hitta lämpligt mappnamn för modpaket $1"
-
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"\n"
-"Modinstallation: ej stöd för filtyp \"$1\" eller trasigt arkiv"
+msgstr "Moddinstallation: lyckas ej hitta lämpligt mappnamn för moddpaket $1"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: file: \"$1\""
-msgstr "Modinstallation: fil: \"$1\""
-
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "Unable to find a valid mod or modpack"
-msgstr "Modinstallation: lyckas ej hitta lämpligt mappnamn för modpaket $1"
+msgstr "Lyckades ej hitta lämplig modd eller moddpaket"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "Unable to install a $1 as a texture pack"
-msgstr "Misslyckades installera $1 till $2"
+msgstr "Misslyckades att installera $1 som ett texturpaket"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "Unable to install a game as a $1"
-msgstr "Misslyckades installera $1 till $2"
+msgstr "Misslyckades installera ett spel som en $1"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "Unable to install a mod as a $1"
-msgstr "Misslyckades installera $1 till $2"
+msgstr "Misslyckades installera en modd som en $1"
 
 #: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
 msgid "Unable to install a modpack as a $1"
-msgstr "Misslyckades installera $1 till $2"
+msgstr "Misslyckades installera moddpaket som en $1"
 
 #: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp
 msgid "Loading..."
@@ -808,7 +764,7 @@ msgstr "Laddar..."
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Public server list is disabled"
-msgstr ""
+msgstr "Den offentliga serverlistan är inaktiverad"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
@@ -817,31 +773,31 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Om"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Aktiva Bidragande"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Aktivt avstånd för objektsändning"
+msgstr "Aktiv renderer:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
 msgstr "Huvudutvecklare"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Open User Data Directory"
-msgstr "Välj katalog"
+msgstr "Öppna Användardatamappen"
 
 #: builtin/mainmenu/tab_about.lua
 msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"Öppnar mappen som innehåller världar, spel, moddar,\n"
+"och texturpaket i en filhanterare."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
@@ -853,50 +809,43 @@ msgstr "Före detta huvudutvecklare"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Browse online content"
-msgstr ""
+msgstr "Bläddra bland onlineinnehåll"
 
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "Content"
-msgstr "Fortsätt"
+msgstr "Innehåll"
 
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "Disable Texture Pack"
-msgstr "Välj texturpaket:"
+msgstr "Inaktivera Texturpaket"
 
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "Information:"
-msgstr "Modinformation:"
+msgstr "Information:"
 
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "Installed Packages:"
-msgstr "Installerade moddar:"
+msgstr "Installerade paket:"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "No dependencies."
 msgstr "Inga beroenden."
 
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "No package description available"
-msgstr "Ingen modbeskrivning tillgänglig"
+msgstr "Ingen paketbeskrivning tillgänglig"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Rename"
 msgstr "Byt namn"
 
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "Uninstall Package"
-msgstr "Avinstallera vald mod"
+msgstr "Avinstallera Paket"
 
 #: builtin/mainmenu/tab_content.lua
-#, fuzzy
 msgid "Use Texture Pack"
-msgstr "Texturpaket"
+msgstr "Använd Texturpaket"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Announce Server"
@@ -920,15 +869,15 @@ msgstr "Bilda Spel"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Server"
-msgstr "Bilda Server"
+msgstr "Värdserver"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Install games from ContentDB"
-msgstr ""
+msgstr "Installera spel från ContentDB"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "Namn"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
@@ -939,23 +888,20 @@ msgid "No world created or selected!"
 msgstr "Ingen värld skapad eller vald!"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Password"
-msgstr "Nytt Lösenord"
+msgstr "Lösenord"
 
 #: builtin/mainmenu/tab_local.lua
-#, fuzzy
 msgid "Play Game"
-msgstr "Starta spel"
+msgstr "Starta Spel"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Port"
 msgstr "Port"
 
 #: builtin/mainmenu/tab_local.lua
-#, fuzzy
 msgid "Select Mods"
-msgstr "Välj värld:"
+msgstr "Välj moddar"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select World:"
@@ -966,14 +912,12 @@ msgid "Server Port"
 msgstr "Serverport"
 
 #: builtin/mainmenu/tab_local.lua
-#, fuzzy
 msgid "Start Game"
-msgstr "Bilda Spel"
+msgstr "Starta Spel"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "Bindningsadress"
+msgstr "Adress"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -989,45 +933,40 @@ msgstr "Kreativt läge"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Skada"
+msgstr "Skada / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "Radera Favorit"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favoritmarkera"
+msgstr "Favoriter"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Inkompatibla Servrar"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Join Game"
-msgstr "Bilda Spel"
+msgstr "Anslut Spel"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Offentliggör Server"
+msgstr "Offentliga Servrar"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Uppdatera"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Serverport"
+msgstr "Serverbeskrivning"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1046,16 +985,14 @@ msgid "8x"
 msgstr "8x"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "All Settings"
-msgstr "Inställningar"
+msgstr "Alla Inställningar"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Antialiasing:"
 msgstr "Kantutjämning:"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "Autosave Screen Size"
 msgstr "Spara fönsterstorlek automatiskt"
 
@@ -1069,15 +1006,15 @@ msgstr "Ändra Tangenter"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Connected Glass"
-msgstr "Sammankopplat glas"
+msgstr "Sammanfogat Glas"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "Dynamiska skuggor"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dynamiska skuggor: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1085,15 +1022,15 @@ msgstr "Fina Löv"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Hög"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Låg"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Medium"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1149,11 +1086,11 @@ msgstr "Shaders"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (experimental)"
-msgstr ""
+msgstr "Shaders (experimentella)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
-msgstr ""
+msgstr "Shaders (otillgängliga)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Simple Leaves"
@@ -1167,18 +1104,13 @@ msgstr "Utjämnad Belysning"
 msgid "Texturing:"
 msgstr "Texturering:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "För att aktivera shaders behöver OpenGL-drivern användas."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Tonmappning"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "Touchthreshold: (px)"
-msgstr "Touch-tröskel (px)"
+msgstr "Touch-tröskel: (px)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Trilinear Filter"
@@ -1186,26 +1118,25 @@ msgstr "Trilinjärt filter"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Extremt Hög"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Väldigt Låg"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
 msgstr "Vajande Löv"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "Waving Liquids"
-msgstr "Vajande Löv"
+msgstr "Vajande Vätskor"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Plants"
 msgstr "Vajande Växter"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Anslutningens tidsgräns nådd."
 
@@ -1234,12 +1165,12 @@ msgid "Connection error (timed out?)"
 msgstr "Anslutningsfel (tidsgräns nådd?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Kunde inte hitta eller ladda spel \""
+msgid "Could not find or load game"
+msgstr "Kunde inte hitta eller ladda spel"
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
-msgstr "Ogiltiga spelspecifikationer."
+msgstr "Ogiltig spelspecifikation."
 
 #: src/client/clientlauncher.cpp
 msgid "Main Menu"
@@ -1247,7 +1178,7 @@ msgstr "Huvudmeny"
 
 #: src/client/clientlauncher.cpp
 msgid "No world selected and no address provided. Nothing to do."
-msgstr "Ingen värld vald och ingen adress försed. Inget kan göras."
+msgstr "Ingen värld vald och ingen adress anginven. Inget att göra."
 
 #: src/client/clientlauncher.cpp
 msgid "Player name too long."
@@ -1255,15 +1186,15 @@ msgstr "Spelarnamn för långt."
 
 #: src/client/clientlauncher.cpp
 msgid "Please choose a name!"
-msgstr "Välj ett namn!"
+msgstr "Vänligen välj ett namn!"
 
 #: src/client/clientlauncher.cpp
 msgid "Provided password file failed to open: "
-msgstr ""
+msgstr "Den angivna lösenordsfilen kunde inte öppnas: "
 
 #: src/client/clientlauncher.cpp
 msgid "Provided world path doesn't exist: "
-msgstr "Den angivna sökvägen för världen existerar inte: "
+msgstr "Angiven världssökväg existerar inte: "
 
 #: src/client/game.cpp
 msgid ""
@@ -1271,31 +1202,19 @@ msgid ""
 "Check debug.txt for details."
 msgstr ""
 "\n"
-"Läs debug.txt för detaljer."
+"Se debug.txt för detaljer."
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "- Address: "
-msgstr "Bindningsadress"
-
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Creative Mode: "
-msgstr "Kreativt läge"
-
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Damage: "
-msgstr "Aktivera skada"
+msgstr "- Bindningsadress: "
 
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Läge: "
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "- Port: "
-msgstr "Port"
+msgstr "- Port: "
 
 #: src/client/game.cpp
 msgid "- Public: "
@@ -1311,53 +1230,84 @@ msgid "- Server Name: "
 msgstr "- Servernamn: "
 
 #: src/client/game.cpp
-#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Ett serialiseringsfel uppstod:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Åtkomst nekad. Anledning: %s"
+
+#: src/client/game.cpp
 msgid "Automatic forward disabled"
-msgstr "Tangent för filmiskt länge"
+msgstr "Automatiskt framåt inaktiverad"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Automatic forward enabled"
-msgstr "Tangent för filmiskt länge"
+msgstr "Automatiskt framåt aktiverat"
+
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Blockgränser dolda"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Blockgränser visas för alla block"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Blockgränser visas för det aktuella blocket"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Blockgränser visas för närliggande block"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Camera update disabled"
-msgstr "Av/på-tangent för kamerauppdatering"
+msgstr "Kamerauppdatering inaktiverad"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Camera update enabled"
-msgstr "Av/på-tangent för kamerauppdatering"
+msgstr "Kamerauppdatering aktiverat"
+
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Kan inte visa blockgränser (behöver behörigheten 'basic_debug')"
 
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Ändra Lösenord"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Cinematic mode disabled"
-msgstr "Tangent för filmiskt länge"
+msgstr "Filmiskt länge inaktiverad"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Cinematic mode enabled"
-msgstr "Tangent för filmiskt länge"
+msgstr "Filmiskt länge aktiverat"
+
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Klienten frånkopplades"
 
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
-msgstr ""
+msgstr "Klientsidiga skriptar är inaktiverade"
 
 #: src/client/game.cpp
 msgid "Connecting to server..."
 msgstr "Ansluter till server..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Anslutningen misslyckades av okänd anledning"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Fortsätt"
 
 #: src/client/game.cpp
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "Controls:\n"
 "- %s: move forwards\n"
@@ -1380,15 +1330,20 @@ msgstr ""
 "- %s: rör dig åt vänster\n"
 "- %s: rör dig åt höger\n"
 "- %s: hoppa/klättra\n"
+"- %s: gräv/slå\n"
+"- %s: använd\n"
 "- %s: smyg/rör dig nedåt\n"
 "- %s: släpp föremål\n"
 "- %s: förråd\n"
 "- Mus: vänd/titta\n"
-"- Vänsterklick: gräv/slå\n"
-"- Högerklick: placera/använd\n"
 "- Mushjul: välj föremål\n"
 "- %s: chatt\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Kunde inte lösa adressen: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Skapar klient..."
@@ -1399,16 +1354,15 @@ msgstr "Skapar server..."
 
 #: src/client/game.cpp
 msgid "Debug info and profiler graph hidden"
-msgstr ""
+msgstr "Felsökningsinfo och profileringsgraf gömd"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Debug info shown"
-msgstr "Av/På tangent för debuginformation"
+msgstr "Felsökningsinfo visas"
 
 #: src/client/game.cpp
 msgid "Debug info, profiler graph, and wireframe hidden"
-msgstr ""
+msgstr "Felsökningsinfo, profileringsgraf och wireframe gömd"
 
 #: src/client/game.cpp
 msgid ""
@@ -1440,11 +1394,11 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Disabled unlimited viewing range"
-msgstr ""
+msgstr "Inaktiverat obegränsat visningsområde"
 
 #: src/client/game.cpp
 msgid "Enabled unlimited viewing range"
-msgstr ""
+msgstr "Aktiverat obegränsat visningsområde"
 
 #: src/client/game.cpp
 msgid "Exit to Menu"
@@ -1452,43 +1406,39 @@ msgstr "Avsluta till Meny"
 
 #: src/client/game.cpp
 msgid "Exit to OS"
-msgstr "Avsluta till Operativsystem"
+msgstr "Avsluta till OS"
 
 #: src/client/game.cpp
 msgid "Fast mode disabled"
-msgstr ""
+msgstr "Snabbt läge inaktiverat"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Fast mode enabled"
-msgstr "Skada aktiverat"
+msgstr "Snabbläge aktiverat"
 
 #: src/client/game.cpp
 msgid "Fast mode enabled (note: no 'fast' privilege)"
-msgstr ""
+msgstr "Snabbt läge aktiverat (notera: inget 'fast'-tillstånd)"
 
 #: src/client/game.cpp
 msgid "Fly mode disabled"
-msgstr ""
+msgstr "Flygläge inaktiverat"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Fly mode enabled"
-msgstr "Skada aktiverat"
+msgstr "Flygläge aktiverat"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled (note: no 'fly' privilege)"
-msgstr ""
+msgstr "Flygläge aktiverat (notera: inget 'fast'-tillstånd)"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Fog disabled"
-msgstr "Inaktiverad"
+msgstr "Dimma inaktiverad"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Fog enabled"
-msgstr "aktiverad"
+msgstr "Dimma aktiverat"
 
 #: src/client/game.cpp
 msgid "Game info:"
@@ -1520,25 +1470,23 @@ msgstr "MiB/s"
 
 #: src/client/game.cpp
 msgid "Minimap currently disabled by game or mod"
-msgstr ""
+msgstr "Minimapp för närvarande inaktiverad av spel eller modd"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Enspelarläge"
+msgstr "Flerspelarläge"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
-msgstr ""
+msgstr "Noclipläge inaktiverat"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Noclip mode enabled"
-msgstr "Skada aktiverat"
+msgstr "Noclipläge aktiverat"
 
 #: src/client/game.cpp
 msgid "Noclip mode enabled (note: no 'noclip' privilege)"
-msgstr ""
+msgstr "Noclipläge aktiverat (notera: inget 'noclip'-tillstånd)"
 
 #: src/client/game.cpp
 msgid "Node definitions..."
@@ -1562,7 +1510,7 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "Profiler graph shown"
-msgstr ""
+msgstr "Profileringsgraf visas"
 
 #: src/client/game.cpp
 msgid "Remote server"
@@ -1585,37 +1533,50 @@ msgid "Sound Volume"
 msgstr "Ljudvolym"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Sound muted"
-msgstr "Ljudvolym"
+msgstr "Ljudvolym avstängd"
 
 #: src/client/game.cpp
 msgid "Sound system is disabled"
-msgstr ""
+msgstr "Ljudsystem är inaktiverad"
 
 #: src/client/game.cpp
 msgid "Sound system is not supported on this build"
-msgstr ""
+msgstr "Ljudsystem stöds inte i detta bygge"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Sound unmuted"
-msgstr "Ljudvolym"
+msgstr "Ljud påsatt"
 
 #: src/client/game.cpp
-#, fuzzy, c-format
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Servern kör troligtvist en annan version av %s."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "Kan inte ansluta till %s eftersom IPv6 är inaktiverad"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "Kan inte lyssna på %s eftersom IPv6 är inaktiverad"
+
+#: src/client/game.cpp
+#, c-format
 msgid "Viewing range changed to %d"
-msgstr "Volym ändrad till to %d%%"
+msgstr "Visningsområde ändrad till %d"
 
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range is at maximum: %d"
-msgstr ""
+msgstr "Visningsområde är vid sitt maximala: %d"
 
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range is at minimum: %d"
-msgstr ""
+msgstr "Visningsområde är vid sitt minimala: %d"
 
 #: src/client/game.cpp
 #, c-format
@@ -1624,50 +1585,48 @@ msgstr "Volym ändrad till to %d%%"
 
 #: src/client/game.cpp
 msgid "Wireframe shown"
-msgstr ""
+msgstr "Wireframe visas"
 
 #: src/client/game.cpp
 msgid "Zoom currently disabled by game or mod"
-msgstr ""
+msgstr "Zoom är för närvarande inaktiverad av spel eller modd"
 
 #: src/client/game.cpp
 msgid "ok"
 msgstr "ok"
 
 #: src/client/gameui.cpp
-#, fuzzy
 msgid "Chat hidden"
-msgstr "Chattangent"
+msgstr "Chatt gömd"
 
 #: src/client/gameui.cpp
 msgid "Chat shown"
-msgstr ""
+msgstr "Chatt visas"
 
 #: src/client/gameui.cpp
 msgid "HUD hidden"
-msgstr ""
+msgstr "HUD gömd"
 
 #: src/client/gameui.cpp
 msgid "HUD shown"
-msgstr ""
+msgstr "HUD visas"
 
 #: src/client/gameui.cpp
 msgid "Profiler hidden"
-msgstr ""
+msgstr "Profilering gömd"
 
 #: src/client/gameui.cpp
 #, c-format
 msgid "Profiler shown (page %d of %d)"
-msgstr ""
+msgstr "Profilering visas (sida %d av %d)"
 
 #: src/client/keycode.cpp
 msgid "Apps"
 msgstr "Appar"
 
 #: src/client/keycode.cpp
-#, fuzzy
 msgid "Backspace"
-msgstr "Tillbaka"
+msgstr "Backspace"
 
 #: src/client/keycode.cpp
 msgid "Caps Lock"
@@ -1828,11 +1787,11 @@ msgstr "Rensa OEM"
 
 #: src/client/keycode.cpp
 msgid "Page down"
-msgstr ""
+msgstr "Sida ner"
 
 #: src/client/keycode.cpp
 msgid "Page up"
-msgstr ""
+msgstr "Sida upp"
 
 #: src/client/keycode.cpp
 msgid "Pause"
@@ -1922,21 +1881,29 @@ msgstr "Zoom"
 
 #: src/client/minimap.cpp
 msgid "Minimap hidden"
-msgstr ""
+msgstr "Minimapp gömd"
 
 #: src/client/minimap.cpp
 #, c-format
 msgid "Minimap in radar mode, Zoom x%d"
-msgstr ""
+msgstr "Minimapp i radarläge, Zoom x%d"
 
 #: src/client/minimap.cpp
 #, c-format
 msgid "Minimap in surface mode, Zoom x%d"
-msgstr ""
+msgstr "Minimapp i ytläge, Zoom x%d"
 
 #: src/client/minimap.cpp
 msgid "Minimap in texture mode"
-msgstr ""
+msgstr "Minimapp i texturläge"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Misslyckades att öppna hemsida"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Öppnar hemsida"
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
@@ -1944,7 +1911,7 @@ msgstr "Lösenorden matchar inte!"
 
 #: src/gui/guiConfirmRegistration.cpp
 msgid "Register and Join"
-msgstr ""
+msgstr "Registrera och Anslut"
 
 #: src/gui/guiConfirmRegistration.cpp
 #, c-format
@@ -1955,28 +1922,32 @@ msgid ""
 "Please retype your password and click 'Register and Join' to confirm account "
 "creation, or click 'Cancel' to abort."
 msgstr ""
+"Du håller på att ansluta till den här servern med namnet \"%s\" för den "
+"första gången.\n"
+"Om du fortsätter kommer ett nytt konto med dina uppgifter skapas på "
+"servern.\n"
+"Var snäll och fyll i ditt lösenord och tryck på 'Registrera och Anslut' för "
+"att bekräfta kontoregistrering, eller tryck \"Avbryt\" för att avbryta."
 
 #: src/gui/guiFormSpecMenu.cpp
 msgid "Proceed"
 msgstr "Fortsätt"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Använd\" = klättra neråt"
+msgstr "\"Aux1\" = klättra neråt"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Autoforward"
-msgstr "Framåt"
+msgstr "Autoframåt"
 
 #: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
 msgid "Automatic jumping"
-msgstr ""
+msgstr "Automatiskt hopp"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1984,12 +1955,11 @@ msgstr "Bakåt"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Blockgränser"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Change camera"
-msgstr "Ändra tangenter"
+msgstr "Ändra kamera"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Chat"
@@ -2005,7 +1975,7 @@ msgstr "Konsol"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. range"
-msgstr ""
+msgstr "Min. räckvidd"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Dec. volume"
@@ -2025,7 +1995,7 @@ msgstr "Framåt"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. range"
-msgstr ""
+msgstr "Höj räckvidd"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Inc. volume"
@@ -2071,21 +2041,19 @@ msgstr "Välj räckvidd"
 
 #: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
 msgid "Screenshot"
-msgstr ""
+msgstr "Skärmdump"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Sneak"
 msgstr "Smyg"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Toggle HUD"
-msgstr "Slå av/på flygläge"
+msgstr "Slå av/på HUD"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Toggle chat log"
-msgstr "Slå av/på snabb"
+msgstr "Slå av/på chattlog"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle fast"
@@ -2096,27 +2064,24 @@ msgid "Toggle fly"
 msgstr "Slå av/på flygläge"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Toggle fog"
-msgstr "Slå av/på flygläge"
+msgstr "Slå av/på dimma"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Toggle minimap"
-msgstr "Slå av/på noclip"
+msgstr "Slå av/på minimapp"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle noclip"
 msgstr "Slå av/på noclip"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "Toggle pitchmove"
-msgstr "Slå av/på snabb"
+msgstr "Slå av/på pitchmove"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "press key"
-msgstr "tryck på tangent"
+msgstr "tryck på knapp"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Change"
@@ -2139,13 +2104,13 @@ msgid "Exit"
 msgstr "Avsluta"
 
 #: src/gui/guiVolumeChange.cpp
-#, fuzzy
 msgid "Muted"
-msgstr "Tysta"
+msgstr "Tyst"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Ljudvolym: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Ljudvolym: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2165,6 +2130,9 @@ msgid ""
 "(Android) Fixes the position of virtual joystick.\n"
 "If disabled, virtual joystick will center to first-touch's position."
 msgstr ""
+"(Android) Fastställer den virtuella joystickens position.\n"
+"Om inaktiverad centreras den virtuella joysticken till det första "
+"fingertryckets position."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2172,9 +2140,11 @@ msgid ""
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
+"(Android) Använd den virtuella joysticken för \"Aux1\"-knappen.\n"
+"Om aktiverad kommer den virtuella joysticken att aktivera \"Aux1\"-knappen "
+"när den är utanför huvudcirkeln."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(X,Y,Z) offset of fractal from world center in units of 'scale'.\n"
 "Can be used to move a desired point to (0, 0) to create a\n"
@@ -2186,10 +2156,13 @@ msgid ""
 "Range roughly -2 to 2. Multiply by 'scale' for offset in nodes."
 msgstr ""
 "(X,Y,Z) förskjutning av fraktal från världscenter i enheten 'skala'.\n"
-"Används för att flytta ett passande spawn-område av lågland nära (0, 0).\n"
-"Ursprungsvärdena passar mandelbrotmängder, de behöver ändras för "
-"juliamängder.\n"
-"Värden mellan -2 to 2. Multiplicera med 'skala' för avvikelse i noder."
+"Kan användas för att förflytta en punkt till (0, 0) för att skapa en\n"
+"passande spawnpunkt, eller för att tillåta inzoomning på en specifik\n"
+"punkt genom att höja 'scale'.\n"
+"Ursprungsvärdena passar en spawnpunkt för mandelbrotmängder,\n"
+"den kan behöva ändras i andra situationer.\n"
+"Värdegräns mellan -2 och 2. Multiplicera med 'skala för avvikelse\n"
+"i noder."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2201,34 +2174,41 @@ msgid ""
 "Default is for a vertically-squashed shape suitable for\n"
 "an island, set all 3 numbers equal for the raw shape."
 msgstr ""
+"(X,Y,Z) fraktalens skala i noder.\n"
+"Den riktiga storleken kommer att vara 2 till 3 gånger större.\n"
+"Siffrorna kan göras mycket stora, men fraktalen\n"
+"behöver inte rymmas i världen.\n"
+"Öka dessa för att 'zooma' in i fraktalens detaljer.\n"
+"Standardvärdet är för en vertikalt mosad form som passar för\n"
+"en ö, ställ in alla 3 siffrorna lika för den ursprungliga formen."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of ridged mountains."
-msgstr ""
+msgstr "2D-brus som styr formen/storleken på berg."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of rolling hills."
-msgstr ""
+msgstr "2D-brus som styr formen/storleken av rullande kullar."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the shape/size of step mountains."
-msgstr ""
+msgstr "2D-brus som styr formen/storleken på steppberg."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of ridged mountain ranges."
-msgstr ""
+msgstr "2D-brus som styr storleken/förekomsten av bergskedjor med rågångar."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of rolling hills."
-msgstr ""
+msgstr "2D-brus som styr storleken/förekomsten av rullande kullar."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of step mountain ranges."
-msgstr ""
+msgstr "2D-brus som styr storleken/förekomsten av bergskedjor med rågångar."
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that locates the river valleys and channels."
-msgstr ""
+msgstr "2D-brus som lokaliserar floddalar och kanaler."
 
 #: src/settings_translation_file.cpp
 msgid "3D clouds"
@@ -2240,7 +2220,7 @@ msgstr "3D-läge"
 
 #: src/settings_translation_file.cpp
 msgid "3D mode parallax strength"
-msgstr ""
+msgstr "Parallaxstyrka i 3D-läge"
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining giant caverns."
@@ -2261,26 +2241,30 @@ msgid ""
 "to be adjusted, as floatland tapering functions best when this noise has\n"
 "a value range of approximately -2.0 to 2.0."
 msgstr ""
+"3D-brus som definierar strukturen hos floatlands.\n"
+"Om det ändras från standardvärdet kan brusets 'skala' (vanligtvist 0.7) "
+"behöva\n"
+"justeras, eftersom avsmalningen av floatlands fungerar bäst när detta brus "
+"har\n"
+"ett värdeintervall på ungefär -2.0 till 2.0."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise defining structure of river canyon walls."
 msgstr "3D oljudsdefiniering av strukturen av floddalsväggar."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "3D noise defining terrain."
-msgstr "3D oljudsdefinierade jättegrottor"
+msgstr "3D brusdefinierad terräng."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations."
-msgstr ""
+msgstr "3D-brus för bergsöverhäng, klippor osv. Vanligtvist små variationer."
 
 #: src/settings_translation_file.cpp
 msgid "3D noise that determines number of dungeons per mapchunk."
-msgstr ""
+msgstr "3D-brus som bestämmer antalet fängelsehålor per mappchunk."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "3D support.\n"
 "Currently supported:\n"
@@ -2300,7 +2284,9 @@ msgstr ""
 "-    interlaced: skärmstöd för ojämn/jämn linjebaserad polarisering.\n"
 "-    topbottom: split screen över/under.\n"
 "-    sidebyside: split screen sida vid sida.\n"
-"-    pageflip: quadbufferbaserad 3d."
+"-    crossview: Korsögad 3d\n"
+"-    pageflip: quadbufferbaserad 3d.\n"
+"Notera att 'interlaced'-läget kräver shaders."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2320,16 +2306,15 @@ msgstr "Ett meddelande som visas för alla klienter när servern stängs ner."
 
 #: src/settings_translation_file.cpp
 msgid "ABM interval"
-msgstr ""
+msgstr "ABM-intervall"
 
 #: src/settings_translation_file.cpp
 msgid "ABM time budget"
-msgstr ""
+msgstr "ABM-tidsbudget"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Absolute limit of queued blocks to emerge"
-msgstr "Absolut gräns av emerge kö"
+msgstr "Absolut gräns för köade block att framträda"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration in air"
@@ -2337,16 +2322,15 @@ msgstr "Acceleration i luften"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration of gravity, in nodes per second per second."
-msgstr ""
+msgstr "Accelerering av gravitation, i noder per sekund per sekund."
 
 #: src/settings_translation_file.cpp
 msgid "Active Block Modifiers"
 msgstr "Aktiva Blockmodifierare"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Active block management interval"
-msgstr "Aktivt Blockhanteringsintervall"
+msgstr "Aktivt blockhanteringsintervall"
 
 #: src/settings_translation_file.cpp
 msgid "Active block range"
@@ -2379,6 +2363,12 @@ msgstr ""
 "Justera dpi-konfigurationen för din skärm (endast icke X11/Android) t.ex. "
 "för 4k-skärmar."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+"Justera den identifierade skärmdensiteten, vilket används för skalning av "
+"gränssnittet."
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2388,6 +2378,11 @@ msgid ""
 "Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n"
 "to be sure) creates a solid floatland layer."
 msgstr ""
+"Justerar tätheten hos floatlandslagret.\n"
+"Öka värdet för att öka tätheten. Kan vara positiv eller negativ.\n"
+"Värde = 0.0: 50% av volymen är floatland.\n"
+"Värde = 2.0 (kan vara högre beroende på 'mgv7_np_floatland', testa alltid\n"
+"för att vara säker) skapar ett fast floatlandslager."
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
@@ -2401,6 +2396,12 @@ msgid ""
 "This only has significant effect on daylight and artificial\n"
 "light, it has very little effect on natural night light."
 msgstr ""
+"Ändrar ljuskurvan genom att tillämpa 'gammakorrigering' på den.\n"
+"Högre värden leder till att de mellersta och lägre ljusnivåerna blir "
+"ljusare.\n"
+"Värdet '1.0' lämnar ljuskurvan oförändrad. Detta har endast betydande\n"
+"effekt på dagsljus och konstgjort ljus, det har väldigt liten effekt på\n"
+"naturligt nattljus."
 
 #: src/settings_translation_file.cpp
 msgid "Always fly and fast"
@@ -2412,12 +2413,11 @@ msgstr "Ambient ocklusion gamma"
 
 #: src/settings_translation_file.cpp
 msgid "Amount of messages a player may send per 10 seconds."
-msgstr ""
+msgstr "Antal meddelanden en spelare får skicka per 10 sekunder."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Amplifies the valleys."
-msgstr "Amplifiera dalgångar"
+msgstr "Amplifierar dalgångarna."
 
 #: src/settings_translation_file.cpp
 msgid "Anisotropic filtering"
@@ -2428,17 +2428,16 @@ msgid "Announce server"
 msgstr "Offentliggör server"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Announce to this serverlist."
-msgstr "Offentliggör server"
+msgstr "Annonsera till serverlistan."
 
 #: src/settings_translation_file.cpp
 msgid "Append item name"
-msgstr ""
+msgstr "Infoga objektnamn"
 
 #: src/settings_translation_file.cpp
 msgid "Append item name to tooltip."
-msgstr ""
+msgstr "Infoga objektnamn till verktygstips."
 
 #: src/settings_translation_file.cpp
 msgid "Apple trees noise"
@@ -2446,20 +2445,21 @@ msgstr "Äppelträdlojud"
 
 #: src/settings_translation_file.cpp
 msgid "Arm inertia"
-msgstr ""
+msgstr "Armtröghet"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Arm inertia, gives a more realistic movement of\n"
 "the arm when the camera moves."
 msgstr ""
+"Armtröghet, ger mer realistisk rörelse av armen\n"
+"när kameran förflyttar sig."
 
 #: src/settings_translation_file.cpp
 msgid "Ask to reconnect after crash"
 msgstr "Förfråga att återkoppla efter krash"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "At this distance the server will aggressively optimize which blocks are sent "
 "to\n"
@@ -2473,27 +2473,28 @@ msgid ""
 "optimization.\n"
 "Stated in mapblocks (16 nodes)."
 msgstr ""
-"Vid detta avstånd kommer servern att aggressivt omtimera vilka block som "
-"skickas till klienterna.\n"
+"Vid detta avstånd kommer servern att aggressivt optimera vilka block som "
+"skickas till\n"
+"klienterna.\n"
 "Små värden kan potentiellt förbättra prestandan avsevärt, på bekostnaden av "
-"synliga renderingsglitchar.\n"
-"(vissa block kommer inte att renderas under vatten och i grottor, ibland "
-"även på land)\n"
+"synliga\n"
+"renderingsglitchar (vissa block kommer inte att renderas under vatten och i "
+"grottor,\n"
+"ibland även på land).\n"
 "Sätts detta till ett värde större än max_block_send_distance inaktiveras "
-"denna optimering.\n"
-"Angiven i mapblocks (16 noder)"
+"denna\n"
+"optimering.\n"
+"Angiven i mapblocks (16 noder)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatic forward key"
-msgstr "Tangent för filmiskt länge"
+msgstr "Automatisk framåtknapp"
 
 #: src/settings_translation_file.cpp
 msgid "Automatically jump up single-node obstacles."
-msgstr ""
+msgstr "Hoppa automatiskt upp över enstaka noder hinder."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatically report to the serverlist."
 msgstr "Rapportera automatiskt till serverlistan."
 
@@ -2503,15 +2504,15 @@ msgstr "Spara fönsterstorlek automatiskt"
 
 #: src/settings_translation_file.cpp
 msgid "Autoscaling mode"
-msgstr ""
+msgstr "Automatiskt skalningsläge"
 
 #: src/settings_translation_file.cpp
 msgid "Aux1 key"
-msgstr ""
+msgstr "Aux1-knappen"
 
 #: src/settings_translation_file.cpp
 msgid "Aux1 key for climbing/descending"
-msgstr ""
+msgstr "Aux1-knappen för klättring/sjunkning"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2519,21 +2520,19 @@ msgstr "Bakåttangent"
 
 #: src/settings_translation_file.cpp
 msgid "Base ground level"
-msgstr ""
+msgstr "Grundnivå"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Base terrain height."
-msgstr "Bas för terränghöjd"
+msgstr "Bas för terränghöjd."
 
 #: src/settings_translation_file.cpp
 msgid "Basic"
 msgstr "Grundläggande"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Basic privileges"
-msgstr "Grundläggande Privilegier"
+msgstr "Grundläggande privilegier"
 
 #: src/settings_translation_file.cpp
 msgid "Beach noise"
@@ -2561,23 +2560,23 @@ msgstr "Biotopoljud"
 
 #: src/settings_translation_file.cpp
 msgid "Block send optimize distance"
-msgstr ""
+msgstr "Distans för optimering av blockskickning"
 
 #: src/settings_translation_file.cpp
 msgid "Bold and italic font path"
-msgstr ""
+msgstr "Fet och kursiv typsnittssökväg"
 
 #: src/settings_translation_file.cpp
 msgid "Bold and italic monospace font path"
-msgstr ""
+msgstr "Fet och kursiv monospace-typsnittssökväg"
 
 #: src/settings_translation_file.cpp
 msgid "Bold font path"
-msgstr ""
+msgstr "Fet typsnittssökväg"
 
 #: src/settings_translation_file.cpp
 msgid "Bold monospace font path"
-msgstr ""
+msgstr "Fet monospace-typsnittssökväg"
 
 #: src/settings_translation_file.cpp
 msgid "Build inside player"
@@ -2594,6 +2593,11 @@ msgid ""
 "Increasing can reduce artifacting on weaker GPUs.\n"
 "0.1 = Default, 0.25 = Good value for weaker tablets."
 msgstr ""
+"Kameraavståndet 'nära urklippsplan' i noder, mellan 0 och 0.25\n"
+"Fungerar bara på GLES-plattformar. De flesta användare behöver inte ändra "
+"detta.\n"
+"Ökning kan minska artefakter på svagare GPU:er.\n"
+"0.1 = Standard, 0.25 = Bra värde för svagare tabletter."
 
 #: src/settings_translation_file.cpp
 msgid "Camera smoothing"
@@ -2648,60 +2652,60 @@ msgid "Cavern threshold"
 msgstr "Grottröskel"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Cavern upper limit"
-msgstr "Grottbegränsning"
+msgstr "Övre grottbegränsning"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Center of light curve boost range.\n"
 "Where 0.0 is minimum light level, 1.0 is maximum light level."
 msgstr ""
+"Center för ljuskurvans förstärkningsområde.\n"
+"0.0 är minsta ljusnivå, 1.0 är högsta ljusnivå."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Oljudströskel för öken"
+msgstr "Chattkommando tidströskel"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Chattkommandon"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat font size"
-msgstr "Chunkstorlek"
+msgstr "Chattens typsnittsstorlek"
 
 #: src/settings_translation_file.cpp
 msgid "Chat key"
 msgstr "Chattangent"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat log level"
-msgstr "Nivå av debuglogg"
+msgstr "Chattens loggnivå"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message count limit"
-msgstr ""
+msgstr "Gräns för antalet chattmeddelanden"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat message format"
-msgstr "Krashmeddelande"
+msgstr "Chattmeddelandeformat"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat message kick threshold"
-msgstr "Oljudströskel för öken"
+msgstr "Chattmeddelandens sparkningströskel"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message max length"
-msgstr ""
+msgstr "Högsta längd för chattmeddelande"
 
 #: src/settings_translation_file.cpp
 msgid "Chat toggle key"
 msgstr "Chattangent Av/På"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Chattkommandon"
+msgid "Chat weblinks"
+msgstr "Weblänkar i chatt"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2719,6 +2723,14 @@ msgstr "Tangent för filmiskt länge"
 msgid "Clean transparent textures"
 msgstr "Rena transparenta texturer"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Klickbara weblänkar (mellanklicka eller Ctrl+vänsterklicka) aktiverad i "
+"chattkonsolens utdata."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Klient"
@@ -2732,13 +2744,12 @@ msgid "Client modding"
 msgstr "Klientmoddande"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Client side modding restrictions"
-msgstr "Klientmoddande"
+msgstr "Begränsningar för klientmoddning"
 
 #: src/settings_translation_file.cpp
 msgid "Client side node lookup range restriction"
-msgstr ""
+msgstr "Begränsing av klientsidig nodsökningsområde"
 
 #: src/settings_translation_file.cpp
 msgid "Climbing speed"
@@ -2765,7 +2776,6 @@ msgid "Colored fog"
 msgstr "Färgad dimma"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
 msgstr "Färgad dimma"
 
@@ -2779,6 +2789,13 @@ msgid ""
 "These flags are independent from Minetest versions,\n"
 "so see a full list at https://content.minetest.net/help/content_flags/"
 msgstr ""
+"Kommaseparerad lista av flaggar som ska döljas i innehållsdatabasen.\n"
+"\"nonfree\" kan användas för att gömma paket som inte kvalifieras som 'fri "
+"programvara',\n"
+"per Free Software Foundations definition.\n"
+"Du kan även specifiera innehållsvarningar.\n"
+"Dessa flaggor är oberoende från Minetest-versioner,\n"
+"så en full lista finns på https://content.minetest.net/help/content_flags/"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2802,6 +2819,30 @@ msgstr ""
 msgid "Command key"
 msgstr "Kommandotangent"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Komprimeringsnivå att använda när mappblock sparas till disk.\n"
+"-1 - använd standardnivå\n"
+"0 - minst komprimering, snabbast\n"
+"9 - bäst komprimering, långsammast"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Komprimeringsnivå att använda när mappblock skickas till klienten.\n"
+"-1 - använd standardnivå\n"
+"0 - minst komprimering, snabbast\n"
+"9 - bäst komprimering, långsammast"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Sammankoppla glas"
@@ -2828,16 +2869,15 @@ msgstr "Konsolhöjd"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Flag Blacklist"
-msgstr ""
+msgstr "ContentDB Flaggsvartlista"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Max Concurrent Downloads"
-msgstr ""
+msgstr "ContentDB Högsta Parallella Nedladdningar"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "ContentDB URL"
-msgstr "Fortsätt"
+msgstr "ContentDB URL"
 
 #: src/settings_translation_file.cpp
 msgid "Continuous forward"
@@ -2848,25 +2888,28 @@ msgid ""
 "Continuous forward movement, toggled by autoforward key.\n"
 "Press the autoforward key again or the backwards movement to disable."
 msgstr ""
+"Kontinuerlig framåtgående rörelse, växlas med hjälp av autoforward-"
+"tagenten.\n"
+"Tryck på autoforward-knappen igen eller på bakåtknappen för att inaktivera."
 
 #: src/settings_translation_file.cpp
 msgid "Controls"
 msgstr "Kontrollerar"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Controls length of day/night cycle.\n"
 "Examples:\n"
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
-"Kontrollerar längden av cyklerna för dag/natt\n"
-"Exempel: 72 = 20min, 360 = 4min, 1 = 24timme, 0 = dag/natt/whatever förblir "
+"Kontrollerar längden av cyklerna för dag/natt.\n"
+"Exempel:\n"
+"72 = 20min, 360 = 4min, 1 = 24timme, 0 = dag/natt/någonting förblir "
 "oförändrat."
 
 #: src/settings_translation_file.cpp
 msgid "Controls sinking speed in liquid."
-msgstr ""
+msgstr "Styr sjunkhastigheten i vätska."
 
 #: src/settings_translation_file.cpp
 msgid "Controls steepness/depth of lake depressions."
@@ -2882,6 +2925,9 @@ msgid ""
 "Value >= 10.0 completely disables generation of tunnels and avoids the\n"
 "intensive noise calculations."
 msgstr ""
+"Kontrollerar tunnlarnas bredd, ett mindre värde ger bredare tunnlar.\n"
+"Värde >= 10.0 inaktiverar helt generering av tunnlar och undviker\n"
+"intensiva brusberäkningar."
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
@@ -2896,11 +2942,12 @@ msgid "Crosshair alpha"
 msgstr "Hårkorsalpha"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
-msgstr "Hårkorsalpha (ogenomskinlighet, mellan 0 och 255)."
+"This also applies to the object crosshair."
+msgstr ""
+"Hårkorsalpha (ogenomskinlighet, mellan 0 och 255).\n"
+"Kontrollerar även objektets hårkorsfärg."
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2911,6 +2958,8 @@ msgid ""
 "Crosshair color (R,G,B).\n"
 "Also controls the object crosshair color"
 msgstr ""
+"Hårkorsfärg (R,G,B).\n"
+"Styr även hårkorsets färg på objektet"
 
 #: src/settings_translation_file.cpp
 msgid "DPI"
@@ -2925,9 +2974,8 @@ msgid "Debug info toggle key"
 msgstr "Av/På tangent för debuginformation"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Debug log file size threshold"
-msgstr "Oljudströskel för öken"
+msgstr "Felsökningslogg storlekströskel"
 
 #: src/settings_translation_file.cpp
 msgid "Debug log level"
@@ -2939,7 +2987,7 @@ msgstr "Tangent för volymsänkning"
 
 #: src/settings_translation_file.cpp
 msgid "Decrease this to increase liquid resistance to movement."
-msgstr ""
+msgstr "Minska detta för att öka vätskans motstånd mot rörelser."
 
 #: src/settings_translation_file.cpp
 msgid "Dedicated server step"
@@ -2974,16 +3022,19 @@ msgid "Default report format"
 msgstr "Standardformat för rapporter"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Default stack size"
-msgstr "Standardspel"
+msgstr "Standardstapelstorlekar"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Definiera kvaliteten på skuggfiltrering.\n"
+"Detta simulerar den mjuka skuggeffekten genom att tillämpa en PCF- eller "
+"Poisson-skiva\n"
+"men använder också mer resurser."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -2994,16 +3045,12 @@ msgid "Defines areas with sandy beaches."
 msgstr "Definierar områden med sandstränder."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines distribution of higher terrain and steepness of cliffs."
-msgstr ""
-"Definierar områden för högre (klipptopp-)terräng och påverkar sluttningen av "
-"klippor."
+msgstr "Definierar distribuering för högre terräng och sluttningen av klippor."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines distribution of higher terrain."
-msgstr "Definierar områden för 'terrain_higher' (klipptoppsteräng)."
+msgstr "Definierar områden för högre terräng."
 
 #: src/settings_translation_file.cpp
 msgid "Defines full size of caverns, smaller values create larger caverns."
@@ -3019,14 +3066,12 @@ msgid "Defines location and terrain of optional hills and lakes."
 msgstr "Definierar plats och terräng för valfria kullar och sjöar."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the base ground level."
-msgstr "Definierar trädområden och trädtäthet."
+msgstr "Definierar basnivån."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the depth of the river channel."
-msgstr "Definierar trädområden och trädtäthet."
+msgstr "Definierar djupet av älvkanalen."
 
 #: src/settings_translation_file.cpp
 msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
@@ -3034,14 +3079,12 @@ msgstr ""
 "Definierar maximal distans för spelarförflyttning i block (0 = oändligt)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the width of the river channel."
-msgstr "Definierar strukturen för storskaliga älvkanaler."
+msgstr "Definierar bredden för älvkanaler."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the width of the river valley."
-msgstr "Definierar områden där träd har äpplen."
+msgstr "Definierar bredden för floddalar."
 
 #: src/settings_translation_file.cpp
 msgid "Defines tree areas and tree density."
@@ -3070,9 +3113,8 @@ msgid "Deprecated Lua API handling"
 msgstr "Obruklig Lua API hantering"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Depth below which you'll find giant caverns."
-msgstr "Djup inunder du kan hitta stora grottor."
+msgstr "Djup neråt där du kan hitta enorma grottor."
 
 #: src/settings_translation_file.cpp
 msgid "Depth below which you'll find large caves."
@@ -3090,13 +3132,12 @@ msgid "Desert noise threshold"
 msgstr "Oljudströskel för öken"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Deserts occur when np_biome exceeds this value.\n"
 "When the 'snowbiomes' flag is enabled, this is ignored."
 msgstr ""
-"Öknar förekommer när np_biome överskridet detta värde.\n"
-"När det nya biotopsystemet aktiveras så ignoreras detta."
+"Öknar förekommer när np_biome överskrider detta värde.\n"
+"Detta ignoreras när 'snowbiomes' flaggen är aktiverad."
 
 #: src/settings_translation_file.cpp
 msgid "Desynchronize block animation"
@@ -3104,7 +3145,7 @@ msgstr "Desynkronisera blockanimation"
 
 #: src/settings_translation_file.cpp
 msgid "Dig key"
-msgstr ""
+msgstr "Gräv-knapp"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3118,107 +3159,123 @@ msgstr "Inaktivera antifusk"
 msgid "Disallow empty passwords"
 msgstr "Tillåt inte tomma lösenord"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "Skalningsfaktor för displaytäthet"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Domännamn för server, att visas i serverlistan."
 
 #: src/settings_translation_file.cpp
 msgid "Double tap jump for fly"
-msgstr ""
+msgstr "Dubbeltryck på hoppknapp för att flyga"
 
 #: src/settings_translation_file.cpp
 msgid "Double-tapping the jump key toggles fly mode."
-msgstr ""
+msgstr "Om du trycker på hoppknappen aktiveras flygläge."
 
 #: src/settings_translation_file.cpp
 msgid "Drop item key"
-msgstr ""
+msgstr "Släpp objekt-tagent"
 
 #: src/settings_translation_file.cpp
 msgid "Dump the mapgen debug information."
-msgstr ""
+msgstr "Dumpa felsökningsinformation för mapgen."
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon maximum Y"
-msgstr ""
+msgstr "Maximalt Y för fängelsehålor"
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon minimum Y"
-msgstr ""
+msgstr "Minimalt Y för fängelsehålor"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dungeon noise"
-msgstr "Grottoljud"
+msgstr "Grottbrus"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable IPv6 support (for both client and server).\n"
 "Required for IPv6 connections to work at all."
 msgstr ""
+"Aktivera IPv6-stöd (för både klient och server).\n"
+"Krävs för att IPv6-anslutningar ska fungera."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable Lua modding support on client.\n"
 "This support is experimental and API can change."
 msgstr ""
+"Aktivera stöd för Lua-modifiering på klienten.\n"
+"Detta är experimentellt och API:et kan ändras."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Aktivera Poisson-diskfiltrering.\n"
+"När aktiverad används Poisson-disk för att göra \"mjuka skuggor\". Annars "
+"används PCF-filtrering."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Aktivera färgade skuggor.\n"
+"När aktiverad kastar genomskinliga noder färgade skuggor. Detta är intensivt."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
-msgstr ""
+msgstr "Aktivera konsollfönster"
 
 #: src/settings_translation_file.cpp
 msgid "Enable creative mode for all players"
-msgstr ""
+msgstr "Aktivera kreativt läge för alla spelare"
 
 #: src/settings_translation_file.cpp
 msgid "Enable joysticks"
-msgstr ""
+msgstr "Aktivera joysticks"
 
 #: src/settings_translation_file.cpp
 msgid "Enable mod channels support."
-msgstr ""
+msgstr "Aktivera stöd för mod-kanaler."
 
 #: src/settings_translation_file.cpp
 msgid "Enable mod security"
-msgstr ""
+msgstr "Aktivera modsäkerhet"
 
 #: src/settings_translation_file.cpp
 msgid "Enable players getting damage and dying."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
+msgstr "Gör det möjligt för spelare att skadas och dö."
 
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
-msgstr ""
+msgstr "Aktivera slumpmässig användarinmatning (används endast för testning)."
 
 #: src/settings_translation_file.cpp
 msgid "Enable register confirmation"
-msgstr ""
+msgstr "Aktivera registreringsbekräftelse"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable register confirmation when connecting to server.\n"
 "If disabled, new account will be registered automatically."
 msgstr ""
+"Aktivera bekräftelse av registrering när du ansluter till servern.\n"
+"När inaktiverad registreras ett nytt konto automatiskt."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable smooth lighting with simple ambient occlusion.\n"
 "Disable for speed or for different looks."
 msgstr ""
+"Möjliggör mjuk belysning med enkel omgivande ocklusion.\n"
+"Inaktivera för prestanda eller för ett annat utseende."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3228,6 +3285,10 @@ msgid ""
 "to new servers, but they may not support all new features that you are "
 "expecting."
 msgstr ""
+"Aktivera för att hindra gamla klienter från att ansluta.\n"
+"Äldre klienter är kompatibla i och med att de inte krashar när de ansluter\n"
+"till nya servrar, men de kanske inte stöder alla nya funktioner du förväntar "
+"dig."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3236,12 +3297,18 @@ msgid ""
 "textures)\n"
 "when connecting to the server."
 msgstr ""
+"Aktivera användning av fjärrmedieserver (om tillhandahålld av servern).\n"
+"Fjärrservrar är ett betydligt snabbare sätt att hämta media (t.ex. "
+"texturer)\n"
+"när du ansluter till servern."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable vertex buffer objects.\n"
 "This should greatly improve graphics performance."
 msgstr ""
+"Aktivera vertexbuffertobjekt.\n"
+"Detta bör avsevärt förbättra grafikprestandan."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3255,6 +3322,9 @@ msgid ""
 "Ignored if bind_address is set.\n"
 "Needs enable_ipv6 to be enabled."
 msgstr ""
+"Aktivera/avaktivera en IPv6-server.\n"
+"Ignoreras om bind_address är angedd.\n"
+"Kräver att enable_ipv6 är aktiverat."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3263,6 +3333,10 @@ msgid ""
 "appearance of high dynamic range images. Mid-range contrast is slightly\n"
 "enhanced, highlights and shadows are gradually compressed."
 msgstr ""
+"Aktiverar Hable's 'Uncharted 2' filmisk tonmappning.\n"
+"Simulerar tonkurvan hos fotografisk film och hur den liknar utseendet\n"
+"på bilder med högt dynamiskt omfång. Kontrasten i mitten av intervallet\n"
+"förstärks något, ljuspunkter och skuggor komprimeras gradvis."
 
 #: src/settings_translation_file.cpp
 msgid "Enables animation of inventory items."
@@ -3270,11 +3344,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Enables caching of facedir rotated meshes."
-msgstr ""
+msgstr "Aktiverar cachning av facedirroterade mesher."
 
 #: src/settings_translation_file.cpp
 msgid "Enables minimap."
-msgstr ""
+msgstr "Aktiverar minimap."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3283,14 +3357,24 @@ msgid ""
 "sound controls will be non-functional.\n"
 "Changing this setting requires a restart."
 msgstr ""
+"Aktiverar ljudsystemet.\n"
+"När inaktiverat inaktiveras alla ljud överallt och spelets\n"
+"ljudkontroller kommer inte fungera.\n"
+"Omstart krävs för att ändra den här inställningen."
 
 #: src/settings_translation_file.cpp
-msgid "Engine profiling data print interval"
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Engine profiling data print interval"
+msgstr "Intervall för utskrift av motorprofileringsdata"
+
 #: src/settings_translation_file.cpp
 msgid "Entity methods"
-msgstr ""
+msgstr "Entitetsmetoder"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3304,53 +3388,55 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "FPS when unfocused or paused"
-msgstr ""
+msgstr "FPS när ofokuserad eller pausad"
 
 #: src/settings_translation_file.cpp
 msgid "FSAA"
-msgstr ""
+msgstr "FSAA"
 
 #: src/settings_translation_file.cpp
 msgid "Factor noise"
-msgstr ""
+msgstr "Faktorbrus"
 
 #: src/settings_translation_file.cpp
 msgid "Fall bobbing factor"
-msgstr ""
+msgstr "Fallets bobbingfaktor"
 
 #: src/settings_translation_file.cpp
 msgid "Fallback font path"
-msgstr ""
+msgstr "Sökväg för reservtypsnitt"
 
 #: src/settings_translation_file.cpp
 msgid "Fast key"
-msgstr ""
+msgstr "Snabbknapp"
 
 #: src/settings_translation_file.cpp
 msgid "Fast mode acceleration"
-msgstr ""
+msgstr "Acceleration i snabbt läge"
 
 #: src/settings_translation_file.cpp
 msgid "Fast mode speed"
-msgstr ""
+msgstr "Hastighet i snabbt läge"
 
 #: src/settings_translation_file.cpp
 msgid "Fast movement"
-msgstr ""
+msgstr "Snabb rörelse"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
+"Snabb rörelse (via \"Aux1\"-tagenten).\n"
+"Detta kräver \"snabb\"-privilegiet på servern."
 
 #: src/settings_translation_file.cpp
 msgid "Field of view"
-msgstr ""
+msgstr "Synfält"
 
 #: src/settings_translation_file.cpp
 msgid "Field of view in degrees."
-msgstr ""
+msgstr "Synfält i grader."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3358,18 +3444,20 @@ msgid ""
 "the\n"
 "Multiplayer Tab."
 msgstr ""
+"Filen i client/serverlist/ som innehåller dina favoritservrar som visas i\n"
+"fliken Anslut Spel."
 
 #: src/settings_translation_file.cpp
 msgid "Filler depth"
-msgstr ""
+msgstr "Fyllnadsdjup"
 
 #: src/settings_translation_file.cpp
 msgid "Filler depth noise"
-msgstr ""
+msgstr "Fyllnadsdjupbrus"
 
 #: src/settings_translation_file.cpp
 msgid "Filmic tone mapping"
-msgstr ""
+msgstr "Filmisk tonmappning"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3381,27 +3469,28 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
-msgstr ""
+msgstr "Filtrering"
 
 #: src/settings_translation_file.cpp
 msgid "First of 4 2D noises that together define hill/mountain range height."
 msgstr ""
+"Första av 4 2D-brus som tillsammans definierar höjden på kullar och berg."
 
 #: src/settings_translation_file.cpp
 msgid "First of two 3D noises that together define tunnels."
-msgstr ""
+msgstr "Första av två 3D-brus som tillsammans definierar tunnlar."
 
 #: src/settings_translation_file.cpp
 msgid "Fixed map seed"
-msgstr ""
+msgstr "Fastställd kartseed"
 
 #: src/settings_translation_file.cpp
 msgid "Fixed virtual joystick"
-msgstr ""
+msgstr "Fast virtuell joystick"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland density"
-msgstr ""
+msgstr "Floatlanddensitet"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland maximum Y"
@@ -3412,9 +3501,8 @@ msgid "Floatland minimum Y"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Floatland noise"
-msgstr "Grottoljud"
+msgstr "Floatlandbrus"
 
 #: src/settings_translation_file.cpp
 msgid "Floatland taper exponent"
@@ -3430,51 +3518,57 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Fly key"
-msgstr ""
+msgstr "Flygknapp"
 
 #: src/settings_translation_file.cpp
 msgid "Flying"
-msgstr ""
+msgstr "Flyga"
 
 #: src/settings_translation_file.cpp
 msgid "Fog"
-msgstr ""
+msgstr "Dimma"
 
 #: src/settings_translation_file.cpp
 msgid "Fog start"
-msgstr ""
+msgstr "Start av dimma"
 
 #: src/settings_translation_file.cpp
 msgid "Fog toggle key"
-msgstr ""
+msgstr "Växlingstagent för dimma"
 
 #: src/settings_translation_file.cpp
 msgid "Font bold by default"
-msgstr ""
+msgstr "Fetstilat typsnitt som standard"
 
 #: src/settings_translation_file.cpp
 msgid "Font italic by default"
-msgstr ""
+msgstr "Kursivt typsnitt som standard"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow"
-msgstr ""
+msgstr "Typsnittsskugga"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow alpha"
-msgstr ""
+msgstr "Genomskinlighet för typsnittsskugga"
 
 #: src/settings_translation_file.cpp
 msgid "Font size"
-msgstr ""
+msgstr "Typsnittsstorlek"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
-msgstr ""
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Storleken för standardtypsnittet i punkter (pt)."
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr "Storleken för monospacetypsnittet i punkter (pt)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3482,6 +3576,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3491,70 +3596,69 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Format of screenshots."
-msgstr ""
+msgstr "Format för skärmdumpar."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Color"
-msgstr ""
+msgstr "Formspec Standardbakgrundsfärg"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Opacity"
-msgstr ""
+msgstr "Formspec Standardbakgrundsopacitet"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Color"
-msgstr ""
+msgstr "Formspec Standardbakgrundsfärg för fullskärm"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Full-Screen Background Opacity"
-msgstr ""
+msgstr "Formspec Standardbakgrundsopacitet för fullskärm"
 
 #: src/settings_translation_file.cpp
 msgid "Formspec default background color (R,G,B)."
-msgstr ""
+msgstr "Formspec Standardbakgrundsfärg (R,G,B)."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec default background opacity (between 0 and 255)."
-msgstr ""
+msgstr "Formspec standardbakgrundsopacitet (mellan 0 och 255)."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec full-screen background color (R,G,B)."
-msgstr ""
+msgstr "Formspec bakgrundsfärg för fullskärm (R,G,B)."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec full-screen background opacity (between 0 and 255)."
-msgstr ""
+msgstr "Formspec bakgrundsopacitet för fullskärm (mellan 0 och 255)."
 
 #: src/settings_translation_file.cpp
 msgid "Forward key"
-msgstr ""
+msgstr "Framåtknapp"
 
 #: src/settings_translation_file.cpp
 msgid "Fourth of 4 2D noises that together define hill/mountain range height."
 msgstr ""
+"Fyra av 4 2D-brus som tillsammans definerar höjden för kullar och berg."
 
 #: src/settings_translation_file.cpp
 msgid "Fractal type"
-msgstr ""
+msgstr "Fraktaltyp"
 
 #: src/settings_translation_file.cpp
 msgid "Fraction of the visible distance at which fog starts to be rendered"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
+msgstr "Bråkdel av den synliga distansen som dimma börjar"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
 "nodes)."
 msgstr ""
+"Hur långt bort block genereras för klienter, mätt i mappblock (16 noder)."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are sent to clients, stated in mapblocks (16 nodes)."
 msgstr ""
+"Från hur långt block skickas till klienten, mätt i mappblock (16 noder)."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3567,33 +3671,33 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Full screen"
-msgstr ""
+msgstr "Fullskärm"
 
 #: src/settings_translation_file.cpp
 msgid "Fullscreen mode."
-msgstr ""
+msgstr "Fullskärmsläge."
 
 #: src/settings_translation_file.cpp
 msgid "GUI scaling"
-msgstr ""
+msgstr "Gränssnittsskalning"
 
 #: src/settings_translation_file.cpp
 msgid "GUI scaling filter"
-msgstr ""
+msgstr "Filter för Gränssnittsskalning"
 
 #: src/settings_translation_file.cpp
 msgid "GUI scaling filter txr2img"
-msgstr ""
+msgstr "Filter för Gränssnittsskalning txr2img"
 
 #: src/settings_translation_file.cpp
 msgid "Global callbacks"
-msgstr ""
+msgstr "Globala återkallelser"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3610,32 +3714,31 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Graphics"
-msgstr ""
+msgstr "Grafik"
 
 #: src/settings_translation_file.cpp
 msgid "Gravity"
-msgstr ""
+msgstr "Gravitation"
 
 #: src/settings_translation_file.cpp
 msgid "Ground level"
-msgstr ""
+msgstr "Marknivå"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Ground noise"
-msgstr "Grottoljud"
+msgstr "Ytbrus"
 
 #: src/settings_translation_file.cpp
 msgid "HTTP mods"
-msgstr ""
+msgstr "HTTP-moddar"
 
 #: src/settings_translation_file.cpp
 msgid "HUD scale factor"
-msgstr ""
+msgstr "HUD-skalningsfaktor"
 
 #: src/settings_translation_file.cpp
 msgid "HUD toggle key"
-msgstr ""
+msgstr "HUD-växlingsknapp"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3656,58 +3759,60 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Heat blend noise"
-msgstr ""
+msgstr "Värmeblandingsbrus"
 
 #: src/settings_translation_file.cpp
 msgid "Heat noise"
-msgstr ""
+msgstr "Värmebrus"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr ""
+msgstr "Höjden av den inledande fönsterstorleken. Ignorerad i fullskärmsläge."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
-msgstr ""
+msgstr "Höjdbrus"
 
 #: src/settings_translation_file.cpp
 msgid "Height select noise"
-msgstr ""
+msgstr "Höjdvalbrus"
 
 #: src/settings_translation_file.cpp
 msgid "Hill steepness"
-msgstr ""
+msgstr "Kullslättning"
 
 #: src/settings_translation_file.cpp
 msgid "Hill threshold"
-msgstr ""
+msgstr "Kulltröskel"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness1 noise"
-msgstr ""
+msgstr "Kullig1 brus"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness2 noise"
-msgstr ""
+msgstr "Kullig2 brus"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness3 noise"
-msgstr ""
+msgstr "Kullig3 brus"
 
 #: src/settings_translation_file.cpp
 msgid "Hilliness4 noise"
-msgstr ""
+msgstr "Kullig4 brus"
 
 #: src/settings_translation_file.cpp
 msgid "Homepage of server, to be displayed in the serverlist."
-msgstr ""
+msgstr "Hemsida för servern, som visas i serverlistan."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Horizontal acceleration in air when jumping or falling,\n"
 "in nodes per second per second."
 msgstr ""
+"Horisontell acceleration i luften vid hopp eller fall,\n"
+"i noder per sekund per sekund."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4026,7 +4131,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4110,7 +4215,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4824,9 +4929,8 @@ msgid "Liquid queue purge time"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Liquid sinking"
-msgstr "Nedstigande hastighet"
+msgstr "Vätskesjunkning"
 
 #: src/settings_translation_file.cpp
 msgid "Liquid update interval in seconds."
@@ -4856,9 +4960,8 @@ msgid "Lower Y limit of dungeons."
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Lower Y limit of floatlands."
-msgstr "Absolut gräns av emerge kö"
+msgstr "Nedre Y-gräns för floatlands."
 
 #: src/settings_translation_file.cpp
 msgid "Main menu script"
@@ -4941,7 +5044,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4969,46 +5072,40 @@ msgid "Mapgen Carpathian specific flags"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Flat"
-msgstr "Kartgenerator"
+msgstr "Mapgen Platt"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen Flat specific flags"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Fractal"
-msgstr "Kartgenerator"
+msgstr "Mapgen Fraktal"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Fractal specific flags"
-msgstr "Kartgenerator"
+msgstr "Specifika flaggar för fraktal"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen V5"
-msgstr "Kartgenerator"
+msgstr "Kartgenerator V5"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen V5 specific flags"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen V6"
-msgstr "Kartgenerator"
+msgstr "Kartgenerator V6"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen V6 specific flags"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen V7"
-msgstr "Kartgenerator"
+msgstr "Kartgenerator V7"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen V7 specific flags"
@@ -5240,7 +5337,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5251,6 +5348,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5372,7 +5473,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5396,11 +5497,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5423,17 +5526,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5454,18 +5553,16 @@ msgid "Physics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Pitch move key"
-msgstr "Tangent för filmiskt länge"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Pitch move mode"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Place key"
-msgstr "Tangent för filmiskt länge"
+msgstr "Placeraknapp"
 
 #: src/settings_translation_file.cpp
 msgid "Place repetition interval"
@@ -5490,9 +5587,8 @@ msgid "Player versus player"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Bilinjär filtrering"
+msgstr "Poissonfiltrering"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5539,9 +5635,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5644,9 +5740,8 @@ msgid "River depth"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "River noise"
-msgstr "Grottoljud"
+msgstr "Flodbrus"
 
 #: src/settings_translation_file.cpp
 msgid "River size"
@@ -5761,7 +5856,6 @@ msgid "Selection box width"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Selects one of 18 fractal types.\n"
 "1 = 4D \"Roundy\" Mandelbrot set.\n"
@@ -5783,25 +5877,25 @@ msgid ""
 "17 = 4D \"Mandelbulb\" Mandelbrot set.\n"
 "18 = 4D \"Mandelbulb\" Julia set."
 msgstr ""
-"Val av 18 fractaler från 9 formler.\n"
-"1 = 4D \"Roundy\" mandelbrot set.\n"
-"2 = 4D \"Roundy\" julia set.\n"
-"3 = 4D \"Squarry\" mandelbrot set.\n"
-"4 = 4D \"Squarry\" julia set.\n"
-"5 = 4D \"Mandy Cousin\" mandelbrot set.\n"
-"6 = 4D \"Mandy Cousin\" julia set.\n"
-"7 = 4D \"Variation\" mandelbrot set.\n"
-"8 = 4D \"Variation\" julia set.\n"
-"9 = 3D \"Mandelbrot/Mandelbar\" mandelbrot set.\n"
-"10 = 3D \"Mandelbrot/Mandelbar\" julia set.\n"
-"11 = 3D \"Christmas Tree\" mandelbrot set.\n"
-"12 = 3D \"Christmas Tree\" julia set.\n"
-"13 = 3D \"Mandelbulb\" mandelbrot set.\n"
-"14 = 3D \"Mandelbulb\" julia set.\n"
-"15 = 3D \"Cosine Mandelbulb\" mandelbrot set.\n"
-"16 = 3D \"Cosine Mandelbulb\" julia set.\n"
-"17 = 4D \"Mandelbulb\" mandelbrot set.\n"
-"18 = 4D \"Mandelbulb\" julia set."
+"Val av 18 fraktaler.\n"
+"1 = 4D \"Roundy\" Mandelbrot set.\n"
+"2 = 4D \"Roundy\" Julia set.\n"
+"3 = 4D \"Squarry\" Mandelbrot set.\n"
+"4 = 4D \"Squarry\" Julia set.\n"
+"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n"
+"6 = 4D \"Mandy Cousin\" Julia set.\n"
+"7 = 4D \"Variation\" Mandelbrot set.\n"
+"8 = 4D \"Variation\" Julia set.\n"
+"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n"
+"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n"
+"11 = 3D \"Christmas Tree\" Mandelbrot set.\n"
+"12 = 3D \"Christmas Tree\" Julia set.\n"
+"13 = 3D \"Mandelbulb\" Mandelbrot set.\n"
+"14 = 3D \"Mandelbulb\" Julia set.\n"
+"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n"
+"16 = 3D \"Cosine Mandelbulb\" Julia set.\n"
+"17 = 4D \"Mandelbulb\" Mandelbrot set.\n"
+"18 = 4D \"Mandelbulb\" Julia set."
 
 #: src/settings_translation_file.cpp
 msgid "Server / Singleplayer"
@@ -5855,26 +5949,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5909,9 +5995,8 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shader path"
-msgstr "Välj sökväg"
+msgstr "Shader-sökväg"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5966,7 +6051,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6041,18 +6126,16 @@ msgid "Sneak key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Sneaking speed"
-msgstr "Nedstigande hastighet"
+msgstr "Smyghastighet"
 
 #: src/settings_translation_file.cpp
 msgid "Sneaking speed, in nodes per second."
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Molnradie"
+msgstr "Radie för mjuk skugga"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6073,6 +6156,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6146,9 +6237,8 @@ msgid "Terrain base noise"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Terrain height"
-msgstr "Bas för terränghöjd"
+msgstr "Terränghöjd"
 
 #: src/settings_translation_file.cpp
 msgid "Terrain higher noise"
@@ -6184,7 +6274,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6202,7 +6292,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6271,7 +6361,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6361,9 +6451,12 @@ msgid "Tooltip delay"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Touch screen threshold"
-msgstr "Strandoljudströskel"
+msgstr "Tröskelvärde för pekskärm"
+
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
@@ -6414,9 +6507,8 @@ msgid "Upper Y limit of dungeons."
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Upper Y limit of floatlands."
-msgstr "Absolut gräns av emerge kö"
+msgstr "Övre Y-gräns för floatlands."
 
 #: src/settings_translation_file.cpp
 msgid "Use 3D cloud look instead of flat."
@@ -6436,7 +6528,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6600,29 +6692,29 @@ msgid "Waving leaves"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids"
-msgstr "Vajande Löv"
+msgstr "Vajande vätskor"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids wave height"
-msgstr "Böljande Vatten"
+msgstr "Våghöjd för vajande vätskor"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids wave speed"
-msgstr "Vajande Löv"
+msgstr "Våghastighet för vajande vätskor"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids wavelength"
-msgstr "Böljande Vatten"
+msgstr "Våglängd för vajande vätskor"
 
 #: src/settings_translation_file.cpp
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6644,7 +6736,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6652,14 +6744,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6722,9 +6807,8 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "World start time"
-msgstr "Världnamn"
+msgstr "Världsstarttid"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6751,9 +6835,8 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Y of upper limit of large caves."
-msgstr "Absolut gräns av emerge kö"
+msgstr "Y-nivå för högre gräns av stora grottor."
 
 #: src/settings_translation_file.cpp
 msgid "Y-distance over which caverns expand to full size."
@@ -6776,50 +6859,35 @@ msgid "Y-level of cavern upper limit."
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Y-level of higher terrain that creates cliffs."
-msgstr "Y-nivå av lägre terräng och sjöbottnar."
+msgstr "Y-nivå för högre terräng som skapar klippor."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Y-level of lower terrain and seabed."
-msgstr "Y-nivå av lägre terräng och sjöbottnar."
+msgstr "Y-nivå för lägre terräng och sjöbottnar."
 
 #: src/settings_translation_file.cpp
 msgid "Y-level of seabed."
 msgstr "Y-nivå av sjöbotten."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL filhemladdning tidsgräns"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL-timeout"
+msgstr "cURL-interaktivtimeout"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "cURL parallellgräns"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Kreativt läge: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Aktivera skada: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -6904,6 +6972,12 @@ msgstr "cURL parallellgräns"
 #~ msgid "Downloading and installing $1, please wait..."
 #~ msgstr "Laddar ner och installerar $1, vänligen vänta..."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType-typsnitt"
+
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Installera: fil: \"$1\""
+
 #~ msgid "Main"
 #~ msgstr "Huvudsaklig"
 
@@ -6947,6 +7021,9 @@ msgstr "cURL parallellgräns"
 #~ msgid "Start Singleplayer"
 #~ msgstr "Starta Enspelarläge"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "För att aktivera shaders behöver OpenGL-drivern användas."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Slå av/på Filmisk Kamera"
 
@@ -6956,5 +7033,8 @@ msgstr "cURL parallellgräns"
 #~ msgid "Yes"
 #~ msgstr "Ja"
 
+#~ msgid "You died."
+#~ msgstr "Du dog."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index e5ef46096621826ad08c58b8e1460e571ec52b30..709937ea0924b092a2a7435b3a3afcec1c34c40a 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Swahili (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: Swahili <https://hosted.weblate.org/projects/minetest/"
@@ -63,11 +63,6 @@ msgstr "Respawn"
 msgid "You died"
 msgstr "Umekufa."
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Umekufa."
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -99,6 +94,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 #, fuzzy
 msgid "An error occurred in a Lua script:"
@@ -314,6 +313,13 @@ msgstr "Sakinisha"
 msgid "Install missing dependencies"
 msgstr "Inaanzilisha fundo"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+"\n"
+"Sakinisha Moduli: filetype visivyotegemezwa \"$1\" au nyaraka kuvunjwa"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -665,7 +671,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 #, fuzzy
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Umbali wa uhamisho wa mchezaji"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -785,18 +791,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Sakinisha Moduli: haiwezi kupata foldername ya kufaa kwa ajili ya modpack $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-"\n"
-"Sakinisha Moduli: filetype visivyotegemezwa \"$1\" au nyaraka kuvunjwa"
-
-#: builtin/mainmenu/pkgmgr.lua
-#, fuzzy
-msgid "Install: file: \"$1\""
-msgstr "Sakinisha Moduli: faili: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 #, fuzzy
 msgid "Unable to find a valid mod or modpack"
@@ -1192,10 +1186,6 @@ msgstr "Taa laini"
 msgid "Texturing:"
 msgstr "Texturing:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Ili kuwezesha shaders OpenGL ya kiendeshaji inahitaji kutumiwa."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Ramani ya toni"
@@ -1230,7 +1220,7 @@ msgstr "Waving fundo"
 msgid "Waving Plants"
 msgstr "Waving mimea"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Muunganisho limekatika."
 
@@ -1259,7 +1249,8 @@ msgid "Connection error (timed out?)"
 msgstr "Kosa la muunganisho (wakati muafaka?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "Haikuweza kupata wala kupakia mchezo\""
 
 #: src/client/clientlauncher.cpp
@@ -1304,16 +1295,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "Kumfunga anwani"
 
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Creative Mode: "
-msgstr "Hali ya ubunifu"
-
-#: src/client/game.cpp
-#, fuzzy
-msgid "- Damage: "
-msgstr "Uharibifu"
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1338,6 +1319,16 @@ msgstr ""
 msgid "- Server Name: "
 msgstr "Jina la seva"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "Kosa limetokea:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Automatic forward disabled"
@@ -1348,6 +1339,22 @@ msgstr "Ufunguo wa mbele"
 msgid "Automatic forward enabled"
 msgstr "Ufunguo wa mbele"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy
 msgid "Camera update disabled"
@@ -1358,6 +1365,10 @@ msgstr "Kibonye guro Usasishaji wa kamera"
 msgid "Camera update enabled"
 msgstr "Kibonye guro Usasishaji wa kamera"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Badilisha nywila"
@@ -1372,6 +1383,11 @@ msgstr "Hali ya cinematic ufunguo"
 msgid "Cinematic mode enabled"
 msgstr "Hali ya cinematic ufunguo"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "Mteja"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1380,6 +1396,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr "Inaunganisha seva..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Kuendelea"
@@ -1414,6 +1434,11 @@ msgstr ""
 "- kipanya gurudumu: Teua kipengee\n"
 "- T: mazungumzo\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Inaunda mteja..."
@@ -1630,6 +1655,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "Kiwango cha sauti"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, fuzzy, c-format
 msgid "Viewing range changed to %d"
@@ -1976,6 +2016,15 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr "Unamu wa kima cha chini cha ukubwa wa Vichujio"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "Imeshindwa kusakinisha $1 hadi $2"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "MaNenotambulishi hayaoani!"
@@ -2185,7 +2234,8 @@ msgid "Muted"
 msgstr "Ufunguo wa matumizi"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "Kiwango sauti:"
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2420,6 +2470,10 @@ msgstr ""
 "Rekebisha usakinishaji wa dpi kwenye kiwamba chako (yasiyo X11/Android tu) "
 "mfano kwa 4 k skrini."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2710,6 +2764,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr "Kilele cha mlima gorofa Mwandishi ramani"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "Amri majadiliano"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2747,8 +2806,8 @@ msgid "Chat toggle key"
 msgstr "Kibonye guro wa mazungumzo"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Amri majadiliano"
+msgid "Chat weblinks"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2766,6 +2825,12 @@ msgstr "Hali ya cinematic ufunguo"
 msgid "Clean transparent textures"
 msgstr "Unamu angavu safi"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Mteja"
@@ -2849,6 +2914,22 @@ msgstr ""
 msgid "Command key"
 msgstr "Ufunguo wa amri"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Kuunganisha kioo"
@@ -2948,7 +3029,7 @@ msgstr "Crosshair Alfa"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr "Crosshair Alfa (opaqueness kati ya 0 na 255)."
 
 #: src/settings_translation_file.cpp
@@ -3031,8 +3112,8 @@ msgstr "Chaguo-msingi mchezo"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3156,6 +3237,10 @@ msgstr "Lemaza anticheat"
 msgid "Disallow empty passwords"
 msgstr "Usiruhusu nywila tupu"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Kikoa jina la seva, kuonyeshwa katika serverlist ya."
@@ -3204,7 +3289,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3234,13 +3326,6 @@ msgstr "Kuwezesha usalama Moduli"
 msgid "Enable players getting damage and dying."
 msgstr "Wezesha wachezaji kupata uharibifu na kufa."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Wezesha ingizo la mtumiaji nasibu (kutumika tu kwa ajili ya kupima)."
@@ -3341,6 +3426,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Injini ubainishaji wa data ya uchapaji nafasi"
@@ -3546,11 +3637,15 @@ msgid "Font size"
 msgstr "Ukubwa wa fonti"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3559,6 +3654,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3626,11 +3732,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid "FreeType fonts"
-msgstr "Fonti Freetype"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3684,7 +3785,7 @@ msgstr "Callbacks ya kimataifa"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Ramani ya kimataifa kizazi sifa.\n"
 "Katika Mwandishi ramani v6 bendera ya 'kienyeji' udhibiti mapambo yote "
@@ -4178,7 +4279,8 @@ msgstr ""
 "Hii ni kawaida tu zinazohitajika kwa wachangiaji wa msingi/builtin"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Chombo chatcommands kwenye usajili."
 
 #: src/settings_translation_file.cpp
@@ -4268,7 +4370,7 @@ msgid "Joystick button repetition interval"
 msgstr "Kifimbocheza kitufe marudio nafasi"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5427,7 +5529,7 @@ msgstr "Ramani hifadhi muda"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "Pata sasishi kioevu"
 
 #: src/settings_translation_file.cpp
@@ -5757,7 +5859,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5768,6 +5870,11 @@ msgstr "Monospace njia ya fonti"
 msgid "Monospace font size"
 msgstr "Ukubwa wa fonti wa Monospace"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Ukubwa wa fonti wa Monospace"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Mountain height noise"
@@ -5900,9 +6007,10 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "Idadi ya vitalu ziada ambayo inaweza kupakiwa na /clearobjects mara moja.\n"
@@ -5929,11 +6037,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5956,17 +6066,13 @@ msgstr "Njia ya orodha ya unamu. Unamu wote vinatafutizwa kwanza kutoka hapa."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -6082,9 +6188,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6424,26 +6530,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6557,7 +6655,7 @@ msgstr ""
 "Kuanza upya inahitajika baada ya kubadilisha hii."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6673,6 +6771,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6797,7 +6903,7 @@ msgstr "Njia ya unamu"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6815,7 +6921,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6890,9 +6996,10 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr "Unyeti wa Jira kifimbocheza kwa kuzunguka Mwoneko ingame frustum."
 
 #: src/settings_translation_file.cpp
@@ -7005,6 +7112,10 @@ msgstr "Kidokezozana kuchelewa"
 msgid "Touch screen threshold"
 msgstr "Touchthreshold (px)"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -7080,7 +7191,7 @@ msgstr "Tumia uchujaji bilinear wakati upimaji unamu."
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7285,6 +7396,11 @@ msgstr "Waving maji urefu"
 msgid "Waving plants"
 msgstr "Waving mimea"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "Uteuzi kikasha rangi"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7314,7 +7430,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7327,19 +7443,9 @@ msgstr ""
 "1 usiwe na athari inayoonekana isipokuwa uchujaji wa bilinear/trilinear/"
 "anisotropic ni kuwezeshwa."
 
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Kama freetype fonti hutumiwa, inahitaji msaada wa freetype kuwa alikusanya "
-"katika."
-
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7476,24 +7582,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL muda wa upakuzi wa faili"
@@ -7507,6 +7595,14 @@ msgstr "muda wa kuisha wa cURL"
 msgid "cURL parallel limit"
 msgstr "cURL kikomo sambamba"
 
+#, fuzzy
+#~ msgid "- Creative Mode: "
+#~ msgstr "Hali ya ubunifu"
+
+#, fuzzy
+#~ msgid "- Damage: "
+#~ msgstr "Uharibifu"
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7635,6 +7731,10 @@ msgstr "cURL kikomo sambamba"
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "Fonti kivuli Alfa (opaqueness kati ya 0 na 255)."
 
+#, fuzzy
+#~ msgid "FreeType fonts"
+#~ msgstr "Fonti Freetype"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Skrini BPP"
 
@@ -7654,6 +7754,10 @@ msgstr "cURL kikomo sambamba"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 msaada."
 
+#, fuzzy
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Sakinisha Moduli: faili: \"$1\""
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "Kina ya pango kubwa"
@@ -7759,6 +7863,9 @@ msgstr "cURL kikomo sambamba"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Fonti hii itatumika kwa lugha fulani."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Ili kuwezesha shaders OpenGL ya kiendeshaji inahitaji kutumiwa."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Togoa Cinematic"
 
@@ -7768,6 +7875,15 @@ msgstr "cURL kikomo sambamba"
 #~ msgid "Waving water"
 #~ msgstr "Waving maji"
 
+#, fuzzy
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Kama freetype fonti hutumiwa, inahitaji msaada wa freetype kuwa "
+#~ "alikusanya katika."
+
 #, fuzzy
 #~ msgid "Y of upper limit of lava in large caves."
 #~ msgstr "Y ya upper kikomo ya kubwa pseudorandom cellars."
@@ -7775,5 +7891,9 @@ msgstr "cURL kikomo sambamba"
 #~ msgid "Yes"
 #~ msgstr "Ndio"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Umekufa."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 54e3dfa351dfdbeb0eecb00047daa1455d098de6..b7fb6fbf48d19b37113aa496132e7b3ce290080e 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Thai (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2020-07-08 08:41+0000\n"
 "Last-Translator: TZTarzan <khunsatyptiphan@gmail.com>\n"
 "Language-Team: Thai <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -63,11 +63,6 @@ msgstr "เกิดใหม่"
 msgid "You died"
 msgstr "คุณตายแล้ว"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "คุณตายแล้ว"
-
 #: builtin/common/chatcommands.lua
 #, fuzzy
 msgid "Available commands:"
@@ -99,6 +94,10 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 #, fuzzy
 msgid "An error occurred in a Lua script:"
@@ -309,6 +308,11 @@ msgstr "ติดตั้ง"
 msgid "Install missing dependencies"
 msgstr "ไฟล์อ้างอิงที่เลือกใช้ได้:"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "ติดตั้ง: ชนิดแฟ้มที่ไม่สนับสนุน \"$1\" หรือเกิดการเสียหาย"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -643,7 +647,8 @@ msgid "Offset"
 msgstr "ค่าชดเชย"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "ความมีอยู่"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -753,14 +758,6 @@ msgstr "ติดตั้ง Mod: ไม่สามารถค้นหาช
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "ติดตั้ง Mod: ไม่สามารถค้นหาชื่อของโฟลเดอร์ที่เหมาะสมสำหรับ modpack $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "ติดตั้ง: ชนิดแฟ้มที่ไม่สนับสนุน \"$1\" หรือเกิดการเสียหาย"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "ติดตั้ง: ไฟล์:  \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "ค้าหาไม่พบ mod หรือ modpack"
@@ -1137,10 +1134,6 @@ msgstr "โคมไฟเรียบ"
 msgid "Texturing:"
 msgstr "พื้นผิว:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "การเปิดใช้งานต้องมีโปรแกรมควบคุม OpenGL ของ shaders ใช้."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "การแมปโทน"
@@ -1175,7 +1168,7 @@ msgstr "โบกโหนด"
 msgid "Waving Plants"
 msgstr "โบกไม้"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "การเชื่อมต่อหมดเวลา"
 
@@ -1204,7 +1197,8 @@ msgid "Connection error (timed out?)"
 msgstr "ข้อผิดพลาดการเชื่อมต่อ (หมดเวลา?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+#, fuzzy
+msgid "Could not find or load game: "
 msgstr "ไม่สามารถค้นหา หรือโหลดเกม"
 
 #: src/client/clientlauncher.cpp
@@ -1248,14 +1242,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "-ที่อยู่: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "-โหมดสร้างสรรค์: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "-ความเสียหาย: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "-โหมด: "
@@ -1278,6 +1264,16 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "-ชื่อเซิร์ฟเวอร์: "
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "A serialization error occurred:"
+msgstr "เกิดข้อผิดพลาดขึ้น:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "ปิดใช้งานการส่งต่ออัตโนมัติ"
@@ -1286,6 +1282,22 @@ msgstr "ปิดใช้งานการส่งต่ออัตโนม
 msgid "Automatic forward enabled"
 msgstr "เปิดใช้งานการส่งต่ออัตโนมัติ"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "ปิดใช้งานการอัปเดตกล้องแล้ว"
@@ -1294,6 +1306,10 @@ msgstr "ปิดใช้งานการอัปเดตกล้องแ
 msgid "Camera update enabled"
 msgstr "เปิดใช้งานการอัปเดตกล้องแล้ว"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "เปลี่ยนรหัสผ่าน"
@@ -1306,6 +1322,11 @@ msgstr "ปิดใช้งานโหมดภาพยนตร์"
 msgid "Cinematic mode enabled"
 msgstr "เปิดใช้งานโหมดภาพยนตร์"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Client disconnected"
+msgstr "ลูกค้า modding"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "การเขียนสคริปต์ฝั่งไคลเอ็นต์ถูกปิดใช้งาน"
@@ -1314,6 +1335,10 @@ msgstr "การเขียนสคริปต์ฝั่งไคลเอ
 msgid "Connecting to server..."
 msgstr "เชื่อมต่อกับเซิร์ฟเวอร์"
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "ต่อ"
@@ -1351,6 +1376,11 @@ msgstr ""
 "- ล้อเมาส์: เลือกรายการ\n"
 "-%s9: แชท\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "สร้างไคลเอ็นต์..."
@@ -1557,6 +1587,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr "เสียงไม่ปิดเสียง"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1916,6 +1961,15 @@ msgstr "แผนที่ย่อในโหมด surface, ซูม x1"
 msgid "Minimap in texture mode"
 msgstr "ขนาดพื้นผิวขั้นต่ำ"
 
+#: src/gui/guiChatConsole.cpp
+#, fuzzy
+msgid "Failed to open webpage"
+msgstr "ไม่สามารถดาวน์โหลด $1"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "รหัสผ่านไม่ตรงกับ!"
@@ -2118,7 +2172,8 @@ msgid "Muted"
 msgstr "เสียง"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, fuzzy, c-format
+msgid "Sound Volume: %d%%"
 msgstr "ระดับเสียง "
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2348,6 +2403,10 @@ msgstr ""
 "ปรับการกำหนดค่า dpi ให้กับหน้าจอของคุณ (ไม่ใช่ X11 / Android เท่านั้น) เช่น สำหรับหน้าจอ "
 "4k."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2627,6 +2686,11 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Chat commands"
+msgstr "คำสั่ง"
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid "Chat font size"
@@ -2663,8 +2727,9 @@ msgid "Chat toggle key"
 msgstr "ปุ่มสลับการแชท"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr ""
+#, fuzzy
+msgid "Chat weblinks"
+msgstr "สนทนาแสดง"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2682,6 +2747,12 @@ msgstr "ปุ่มโหมดโรงภาพยนตร์"
 msgid "Clean transparent textures"
 msgstr "ทำความสะอาดพื้นผิวโปร่งใส"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "ไคลเอนต์"
@@ -2758,6 +2829,22 @@ msgstr ""
 msgid "Command key"
 msgstr "คีย์คำสั่ง"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "เชื่อมกระจก"
@@ -2852,7 +2939,7 @@ msgstr "Crosshair อัลฟา"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr "Crosshair อัลฟา (ความทึบแสงระหว่าง 0 ถึง 255)."
 
 #: src/settings_translation_file.cpp
@@ -2932,8 +3019,8 @@ msgstr "เกมเริ่มต้น"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3054,6 +3141,10 @@ msgstr "ปิดใช้งาน anticheat"
 msgid "Disallow empty passwords"
 msgstr "ไม่อนุญาตรหัสผ่านที่ว่างเปล่า"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "ชื่อโดเมนของเซิร์ฟเวอร์ที่จะแสดงในรายการเซิร์ฟเวอร์."
@@ -3102,7 +3193,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3131,13 +3229,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr "ช่วยให้ผู้เล่นได้รับความเสียหายและกำลังจะตาย."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "เปิดใช้งานการป้อนข้อมูลผู้ใช้แบบสุ่ม (ใช้สำหรับการทดสอบเท่านั้น)."
@@ -3237,6 +3328,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3436,11 +3533,15 @@ msgid "Font size"
 msgstr "ขนาดตัวอักษร"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3449,6 +3550,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3508,10 +3620,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "เศษส่วนของระยะทางที่มองเห็นซึ่งมีหมอกเริ่มแสดง"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "แบบอักษรประเภท FreeType"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3560,7 +3668,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4007,7 +4115,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4094,7 +4202,7 @@ msgstr "ช่วงเวลาการทำซ้ำปุ่มจอยส
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "ประเภทของจอยสติ๊ก"
 
 #: src/settings_translation_file.cpp
@@ -5154,7 +5262,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5461,7 +5569,8 @@ msgid "Mod channels"
 msgstr "ช่องทาง Mod"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "ปรับเปลี่ยนขนาดขององค์ประกอบ Hudbar."
 
 #: src/settings_translation_file.cpp
@@ -5472,6 +5581,11 @@ msgstr "เส้นทางฟอนต์ monospace"
 msgid "Monospace font size"
 msgstr "ขนาดตัวอักษร Monospace"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "ขนาดตัวอักษร Monospace"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5599,7 +5713,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5623,11 +5737,13 @@ msgid ""
 "open."
 msgstr "เปิดเมนูหยุดชั่วคราวเมื่อโฟกัสของหน้าต่างหายไป ไม่หยุดถ้า formspec คือ เปิด."
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5650,17 +5766,13 @@ msgstr "เส้นทางไปยังไดเรกทอรีพื้
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5772,9 +5884,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6080,26 +6192,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6208,7 +6312,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6323,6 +6427,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, fuzzy
 msgid ""
@@ -6437,7 +6549,7 @@ msgstr "เส้นทางพื้นผิว"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6462,7 +6574,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "ตัวระบุของจอยสติ๊กที่จะใช้"
 
 #: src/settings_translation_file.cpp
@@ -6537,9 +6649,10 @@ msgstr ""
 "รองรับ shader ในขณะนี้"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "ความไวของแกนจอยสติ๊กสำหรับการเลื่อน\n"
 "มุมมอง ingame frustum รอบ ๆ."
@@ -6645,6 +6758,10 @@ msgstr "เคล็ดลับเครื่องมือล่าช้า
 msgid "Touch screen threshold"
 msgstr "ขีด จำกัด หน้าจอสัมผัส"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6723,8 +6840,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "ใช้การกรอง bilinear เมื่อปรับขนาดพื้นผิว"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6920,6 +7038,11 @@ msgstr "โบกมือกันยาว"
 msgid "Waving plants"
 msgstr "โบกต้นไม้"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "สีของกล่องที่เลือก"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6949,7 +7072,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6966,16 +7089,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"ไม่ว่าจะใช้ฟอนต์ FreeType ต้องมีการสนับสนุน FreeType เพื่อรวบรวม\n"
-"หากปิดใช้งาน ฟอนต์บิตแมปและเอ็กซ์เอ็มแอลเวกเตอร์จะใช้แทน"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7116,24 +7230,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -7146,6 +7242,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "-โหมดสร้างสรรค์: "
+
+#~ msgid "- Damage: "
+#~ msgstr "-ความเสียหาย: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7263,6 +7365,9 @@ msgstr ""
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "ตัวอักษรเงาอัลฟา (ความทึบระหว่าง 0 และ 255)."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "แบบอักษรประเภท FreeType"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "BPP เต็มหน้าจอ"
 
@@ -7275,6 +7380,9 @@ msgstr ""
 #~ msgid "Generate normalmaps"
 #~ msgstr "สร้างแผนที่ปกติ"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "ติดตั้ง: ไฟล์:  \"$1\""
+
 #~ msgid "Lightness sharpness"
 #~ msgstr "ความคมชัดของแสง"
 
@@ -7383,6 +7491,9 @@ msgstr ""
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "แบบอักษรนี้จะใช้สำหรับบางภาษา"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "การเปิดใช้งานต้องมีโปรแกรมควบคุม OpenGL ของ shaders ใช้."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "สลับโรงภาพยนตร์"
 
@@ -7392,8 +7503,20 @@ msgstr ""
 #~ msgid "Waving water"
 #~ msgstr "โบกน้ำ"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "ไม่ว่าจะใช้ฟอนต์ FreeType ต้องมีการสนับสนุน FreeType เพื่อรวบรวม\n"
+#~ "หากปิดใช้งาน ฟอนต์บิตแมปและเอ็กซ์เอ็มแอลเวกเตอร์จะใช้แทน"
+
 #~ msgid "Yes"
 #~ msgstr "ใช่"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "คุณตายแล้ว"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index 4e8bc84d945a34e551aed3c4d790ff7e7a5d0925..e68a75653c2b108e6bb368211fc587fd1cad3754 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Turkish (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-03-07 07:10+0000\n"
-"Last-Translator: Oğuz Ersen <oguzersen@protonmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-22 11:52+0000\n"
+"Last-Translator: Mehmet Ali <2045uuttb@relay.firefox.com>\n"
 "Language-Team: Turkish <https://hosted.weblate.org/projects/minetest/"
 "minetest/tr/>\n"
 "Language: tr\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.1\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "Dış sohbet kuyruğunun maksimum boyutu"
+msgstr "Dış sohbet kuyruğunu temizle"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Sohbet komutları"
+msgstr "Boş komut."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Menüye Çık"
+msgstr "Ana menüye çık"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Yerel komut"
+msgstr "Geçersiz komut: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Verilen komut: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Tek oyunculu"
+msgstr "Çevrim içi oyuncuları listele"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Tek oyunculu"
+msgstr "Çevrim içi oyuncular: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Dış sohbet kuyruğu artık boş."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Bu komut sunucu tarafından devre dışı bırakıldı."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,41 @@ msgstr "Yeniden Canlan"
 msgid "You died"
 msgstr "Öldün"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Öldün"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Yerel komut"
+msgstr "Kullanılabilir komutlar:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Yerel komut"
+msgstr "Kullanılabilir komutlar: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Komut kullanılamıyor: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Komutlar için yardım alın"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Daha fazla bilgi almak için '.help <komut>' veya her şeyi listelemek için '."
+"help all' kullanın."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <komut>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "Tamam"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<mevcut değil>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua betiğinde bir hata oluştu:"
@@ -275,7 +268,7 @@ msgstr "Yerel oyun:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
-msgstr "Minetest cURL'siz derlediğinde ContentDB kullanılamaz"
+msgstr "Minetest cURL olmadan derlendiğinde ContentDB kullanılamaz"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Downloading..."
@@ -302,6 +295,10 @@ msgstr "$1 kur"
 msgid "Install missing dependencies"
 msgstr "Eksik bağımlılıkları kur"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Kur: Desteklenmeyen dosya türü veya bozuk arşiv"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -345,7 +342,7 @@ msgstr "Kaldır"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update"
-msgstr "Güncelle"
+msgstr "Güncelleme"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
@@ -631,7 +628,7 @@ msgid "Offset"
 msgstr "Kaydırma"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Süreklilik"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -741,14 +738,6 @@ msgstr "Mod Kur: $1 için gerçek mod adı bulunamadı"
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "Mod Kur:$1 mod paketi için uygun bir klasör adı bulunamadı"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Kur: Desteklenmeyen dosya türü \"$1\" veya bozuk arşiv"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Kur: dosya: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Geçerli bir mod veya mod paketi bulunamadı"
@@ -775,26 +764,25 @@ msgstr "Yükleniyor..."
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Public server list is disabled"
-msgstr "Açık sunucu listesi devre dışı"
+msgstr "Herkese açık sunucu listesi devre dışı"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
 msgstr ""
-"Açık sunucu listesini tekrar etkinleştirmeyi deneyin ve internet "
-"bağlantınızı doğrulayın."
+"Herkese açık sunucu listesini tekrar etkinleştirmeyi deneyin ve internet "
+"bağlantınızı gözden geçirin."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Hakkında"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "Etkin Katkıda Bulunanlar"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Etkin nesne gönderme uzaklığı"
+msgstr "Etkin işleyici:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -929,9 +917,8 @@ msgid "Start Game"
 msgstr "Oyun Başlat"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Adres: "
+msgstr "Adres"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -947,22 +934,20 @@ msgstr "Yaratıcı kip"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Hasar"
+msgstr "Hasar / Savaş (PvP)"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
-msgstr "Favoriyi Sil"
+msgstr "Sık Kullanılanı Sil"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Favori"
+msgstr "Sık Kullanılanlar"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Uyumsuz Sunucular"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -973,18 +958,16 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Sunucuyu Duyur"
+msgstr "Herkese Açık Sunucular"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Yenile"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
-msgstr "Sunucu açıklaması"
+msgstr "Sunucu Açıklaması"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -1027,13 +1010,12 @@ msgid "Connected Glass"
 msgstr "Bitişik Cam"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "Yazı tipi gölgesi"
+msgstr "Dinamik gölgeler"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Dinamik gölgeler: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1041,15 +1023,15 @@ msgstr "Şık Yapraklar"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Yüksek"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Düşük"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Orta"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1123,10 +1105,6 @@ msgstr "Yumuşak Aydınlatma"
 msgid "Texturing:"
 msgstr "Doku:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "OpenGL sürücüleri seçilmeden gölgelemeler etkinleştirilemez."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Ton Eşleme"
@@ -1141,11 +1119,11 @@ msgstr "Trilineer Filtre"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Çok Yüksek"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Çok Düşük"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1159,7 +1137,7 @@ msgstr "Dalgalanan Sıvılar"
 msgid "Waving Plants"
 msgstr "Dalgalanan Bitkiler"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Bağlantı zaman aşımına uğradı."
 
@@ -1188,8 +1166,8 @@ msgid "Connection error (timed out?)"
 msgstr "Bağlantı hatası (zaman aşımı?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Oyun bulunamıyor veya yüklenemiyor \""
+msgid "Could not find or load game"
+msgstr "Oyun bulunamadı veya yüklenemedi: "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1231,14 +1209,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Adres: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Yaratıcı Kip: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Hasar: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Kip: "
@@ -1249,17 +1219,26 @@ msgstr "- Port: "
 
 #: src/client/game.cpp
 msgid "- Public: "
-msgstr "- Herkes: "
+msgstr "- Herkese Açık: "
 
 #. ~ PvP = Player versus Player
 #: src/client/game.cpp
 msgid "- PvP: "
-msgstr "- Savaş: "
+msgstr "- Savaş (PvP): "
 
 #: src/client/game.cpp
 msgid "- Server Name: "
 msgstr "- Sunucu Adı: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Serileştirme hatası oluştu:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Erişim reddedildi. Neden: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Kendiliğinden ileri devre dışı"
@@ -1268,6 +1247,22 @@ msgstr "Kendiliğinden ileri devre dışı"
 msgid "Automatic forward enabled"
 msgstr "Kendiliğinden ileri etkin"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Blok sınırları gizli"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Blok sınırları tüm bloklar için gösteriliyor"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Blok sınırları geçerli blok için gösteriliyor"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Blok sınırları yakındaki bloklar için gösteriliyor"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Kamera güncelleme devre dışı"
@@ -1276,6 +1271,10 @@ msgstr "Kamera güncelleme devre dışı"
 msgid "Camera update enabled"
 msgstr "Kamera güncelleme etkin"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Blok sınırları gösterilemiyor ('basic_debug' ayrıcalığına ihtiyaç var)"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Parola değiştir"
@@ -1288,6 +1287,10 @@ msgstr "Sinematik kip devre dışı"
 msgid "Cinematic mode enabled"
 msgstr "Sinematik kip etkin"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "İstemci bağlantısı kesildi"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "İstemci tarafı betik devre dışı"
@@ -1296,6 +1299,10 @@ msgstr "İstemci tarafı betik devre dışı"
 msgid "Connecting to server..."
 msgstr "Sunucuya bağlanılıyor..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Bilinmeyen bir nedenle bağlantı başarısız oldu"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Devam et"
@@ -1333,6 +1340,11 @@ msgstr ""
 "- Fare tekerleği: öge seç\n"
 "- %s: sohbet\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Adres çözümlenemedi: %s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "İstemci yaratılıyor..."
@@ -1462,9 +1474,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Mini harita şu anda, oyun veya mod tarafından devre dışı"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Tek oyunculu"
+msgstr "Çok oyunculu"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1538,6 +1549,21 @@ msgstr "Bu inşada ses sistemi desteklenmiyor"
 msgid "Sound unmuted"
 msgstr "Ses açık"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "Sunucu muhtemelen farklı bir %s sürümü çalıştırıyor."
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "IPv6 devre dışı bırakıldığı için %s bağlantısı kurulamıyor"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "IPv6 devre dışı bırakıldığından %s adresinde dinlenemiyor"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1872,6 +1898,14 @@ msgstr "Yüzey kipinde mini harita, Yakınlaştırma x%d"
 msgid "Minimap in texture mode"
 msgstr "Doku kipinde mini harita"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Web sayfası açılamadı"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Web sayfası açılıyor"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "Parolalar eşleşmiyor!"
@@ -1900,9 +1934,8 @@ msgid "Proceed"
 msgstr "İlerle"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Özel\" = aşağı in"
+msgstr "\"Aux1\" = aşağı in"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1914,7 +1947,7 @@ msgstr "Kendiliğinden zıplama"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1922,7 +1955,7 @@ msgstr "Geri"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "Blok sınırları"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2073,8 +2106,9 @@ msgid "Muted"
 msgstr "Ses Kısık"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Ses Seviyesi: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Ses Seviyesi: %%%d"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2098,14 +2132,13 @@ msgstr ""
 "Devre dışı bırakılırsa, sanal joystick merkezi, ilk dokunuş konumu olur."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) \"aux\" düğmesini tetiklemek için sanal joystick kullanın.\n"
-"Etkinleştirilirse, sanal joystick, ana çemberin dışındayken \"aux\" "
+"(Android) \"Aux1\" düğmesini tetiklemek için sanal joystick kullanın.\n"
+"Etkinleştirilirse, sanal joystick, ana çemberin dışındayken \"Aux1\" "
 "düğmesini de dinler."
 
 #: src/settings_translation_file.cpp
@@ -2326,6 +2359,10 @@ msgstr ""
 "Ekranınızın (yalnızca Android/X11 olmayan) dpi yapılandırmasını ayarlayın "
 "ör: 4k ekranlar için."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2461,14 +2498,12 @@ msgid "Autoscaling mode"
 msgstr "Kendiliğinden boyutlandırma kipi"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "Zıplama tuşu"
+msgstr "Aux1 tuşu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "Tırmanma/alçalma için özel tuş"
+msgstr "Tırmanma/alçalma için Aux1 tuşu"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2621,9 +2656,12 @@ msgstr ""
 "0.0 minimum, 1.0 maksimum ışık seviyesidir."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "Sohbet iletisi vurma eşiği"
+msgstr "Sohbet komutu zaman iletisi eşiği"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Sohbet komutları"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2658,8 +2696,8 @@ msgid "Chat toggle key"
 msgstr "Sohbet açma/kapama tuşu"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Sohbet komutları"
+msgid "Chat weblinks"
+msgstr "Sohbet web bağlantıları"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2677,6 +2715,14 @@ msgstr "Sinematik kip tuşu"
 msgid "Clean transparent textures"
 msgstr "Saydam dokuları temizle"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"Sohbet konsolu çıktısında etkinleştirilen tıklanabilir (orta tıklama veya "
+"Ctrl+sol tıklama) web bağlantıları."
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "İstemci"
@@ -2722,9 +2768,8 @@ msgid "Colored fog"
 msgstr "Renkli sis"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Renkli sis"
+msgstr "Renkli gölgeler"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2765,6 +2810,31 @@ msgstr ""
 msgid "Command key"
 msgstr "Komut tuşu"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Harita kütlerini diske kaydederken kullanılacak sıkıştırma düzeyi.\n"
+"-1 - öntanımlı sıkıştırma düzeyini kullan\n"
+"0 - hiçbir sıkıştırma yok, en hızlı\n"
+"9 - en iyi sıkıştırma, en yavaş"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+"Harita kütlerini istemciye(client) gönderirken kullanılacak sıkıştırma "
+"düzeyi.\n"
+"-1 - öntanımlı sıkıştırma düzeyini kullan\n"
+"0 - hiçbir sıkıştırma yok, en hızlı\n"
+"9 - en iyi sıkıştırma, en yavaş"
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "Bitişik cam"
@@ -2866,10 +2936,10 @@ msgstr "Artı saydamlığı"
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 "Artı saydamlığı (solukluk, 0 ile 255 arasında).\n"
-"Ayrıca nesne artı rengini de denetler"
+"Ayrıca nesne artı rengi için de geçerlidir"
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2949,10 +3019,14 @@ msgstr "Öntanımlı yığın boyutu"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"Gölge filtreleme kalitesini tanımla.\n"
+"Bu, bir PCF veya Poisson diski uygulayarak yumuşak gölge efektini taklit "
+"eder,\n"
+"ancak aynı zamanda daha fazla kaynak kullanır."
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3080,6 +3154,10 @@ msgstr "Hile önleme devre dışı"
 msgid "Disallow empty passwords"
 msgstr "Boş parolalara izin verme"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Sunucu listesinde görüntülenecek sunucu alan adı."
@@ -3130,9 +3208,22 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"Poisson disk filtrelemeyi etkinleştir.\n"
+"Doğru ise \"yumuşak gölgeler\" yapmak için Poisson diski kullanır. Değilse "
+"PCF filtreleme kullanır."
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"Renkli gölgeleri etkinleştir.\n"
+"Doğru ise yarı saydam düğümlerde renkli gölgeler oluşturur. Bu fazla kaynak "
+"kullanır."
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3158,13 +3249,6 @@ msgstr "Mod güvenliğini etkinleştir"
 msgid "Enable players getting damage and dying."
 msgstr "Oyuncuların hasar almasını ve ölmesini etkinleştir."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "Rastgele kullanıcı girişini etkinleştir (yalnızca test için)."
@@ -3246,9 +3330,9 @@ msgid ""
 "enhanced, highlights and shadows are gradually compressed."
 msgstr ""
 "Hable'ın 'Uncharted 2' film ton eşlemesini etkinleştirir.\n"
-"Fotoğrafsal film ton eğrisini simüle eder ve bu\n"
+"Fotoğrafsal film ton eğrisini taklit eder ve bu\n"
 "yüksek dinamik aralıklı görüntülerin görünümü yakınlaştırır. Orta-aralık\n"
-"kontrast biraz geliştirilir, vurgular ve gölgeler kademeli olarak "
+"karşıtlık biraz geliştirilir, vurgular ve gölgeler kademeli olarak "
 "sıkıştırılır."
 
 #: src/settings_translation_file.cpp
@@ -3275,6 +3359,12 @@ msgstr ""
 "ses denetimlerinin işlevi olmaz.\n"
 "Bu ayarı değiştirmek, yeniden başlatma gerektirir."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "Motor profilleme veri yazdırma aralığı"
@@ -3337,12 +3427,11 @@ msgid "Fast movement"
 msgstr "Hızlı hareket"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"Hızlı hareket (\"özel\" tuşu ile).\n"
+"Hızlı hareket (\"Aux1\" tuşu ile).\n"
 "Bu, sunucu üzerinde \"hızlı\" yetkisi gerektirir."
 
 #: src/settings_translation_file.cpp
@@ -3359,8 +3448,8 @@ msgid ""
 "the\n"
 "Multiplayer Tab."
 msgstr ""
-"İstemci/sunucu listesi/ içinde Multiplayer Sekmesinde görüntülenen\n"
-"favori sunucularızı içeren dosya."
+"Çok Oyunculu Sekmesinde görüntülenen sık kullanılan sunucularızı içeren\n"
+"istemci/sunucu listesi/ içindeki dosya."
 
 #: src/settings_translation_file.cpp
 msgid "Filler depth"
@@ -3375,7 +3464,6 @@ msgid "Filmic tone mapping"
 msgstr "Filmsel ton eşleme"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3387,7 +3475,8 @@ msgstr ""
 "şeffaf komşuları ile RGB değerlerini kaynaştırabilir, bazen şeffaf "
 "dokularda\n"
 "karanlık veya aydınlık kenarlara neden olabilir. Bunu temizlemek için bu\n"
-"filtreyi doku yükleme zamanında uygulayın."
+"filtreyi doku yükleme zamanında uygulayın. Bu, mip eşleme etkinleştirilirse\n"
+"otomatik olarak etkinleştirilir."
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3478,11 +3567,17 @@ msgid "Font size"
 msgstr "Yazı tipi boyutu"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Öntanımlı yazı tipinin nokta (pt) olarak boyutu."
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "Eş aralıklı yazı tipinin nokta (pt) olarak boyutu."
 
 #: src/settings_translation_file.cpp
@@ -3494,6 +3589,17 @@ msgstr ""
 "boyutu.\n"
 "0 değer öntanımlı yazı tipi boyutunu kullanır."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3556,10 +3662,6 @@ msgstr "Fraktal türü"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "Sisin işlenmeye başlayacağı görünebilir uzaklığın kesiri"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "Freetype yazı tipleri"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3615,10 +3717,11 @@ msgid "Global callbacks"
 msgstr "Genel geri çağrılar"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "Genel harita üretim özellikleri.\n"
 "Mapgen v6'da 'decorations' bayrağı ağaçlar ve cangıl çimi hariç tüm "
@@ -3630,16 +3733,16 @@ msgid ""
 "Gradient of light curve at maximum light level.\n"
 "Controls the contrast of the highest light levels."
 msgstr ""
-"Maksimum ışık seviyesinde ışık eğrisinin gradyantı.\n"
-"En yüksek ışık düzeylerinin kontrastını denetler."
+"Azami ışık seviyesinde ışık eğrisinin gradyantı.\n"
+"En yüksek ışık düzeylerinin karşıtlığını denetler."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Gradient of light curve at minimum light level.\n"
 "Controls the contrast of the lowest light levels."
 msgstr ""
-"Minimum ışık seviyesinde ışık eğrisinin gradyantı.\n"
-"En düşük ışık düzeylerinin kontrastını kontrol eder."
+"Asgari ışık seviyesinde ışık eğrisinin gradyantı.\n"
+"En düşük ışık düzeylerinin karşıtlığını denetler."
 
 #: src/settings_translation_file.cpp
 msgid "Graphics"
@@ -3705,10 +3808,10 @@ msgid "Heat noise"
 msgstr "Isı gürültüsü"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "İlk pencere boyutunun yükseklik bileşeni."
+msgstr ""
+"İlk pencere boyutunun yükseklik bileşeni. Tam ekran kipinde yok sayılır."
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3963,12 +4066,11 @@ msgstr ""
 "tüketmemek için, uykuya dalarak sınırla."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
 msgstr ""
-"Devre dışı bırakılırsa \"özel\" tuşu, hem uçma hem de hızlı kipi etkin ise,\n"
+"Devre dışı bırakılırsa \"Aux1\" tuşu, hem uçma hem de hızlı kipi etkin ise,\n"
 "hızlı uçma için kullanılır."
 
 #: src/settings_translation_file.cpp
@@ -3995,13 +4097,12 @@ msgstr ""
 "Bu, sunucuda \"hayalet\" yetkisi gerektirir."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"Etkinleştirilirse, \"sızma\" tuşu yerine \"özel\" tuşu aşağı inme ve "
+"Etkinleştirilirse, \"sızma\" tuşu yerine \"Aux1\" tuşu aşağı inme ve "
 "alçalma\n"
 "için kullanılır."
 
@@ -4015,7 +4116,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "If enabled, disable cheat prevention in multiplayer."
-msgstr "Etkinleştirilirse, multiplayer'da hile önleme devre dışı bırakılır."
+msgstr "Etkinleştirilirse, çok oyunculuda hile önleme devre dışı bırakılır."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4061,6 +4162,9 @@ msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"Bir sohbet komutunun yürütülmesi, saniye cinsinden bu belirtilen süreden "
+"daha\n"
+"uzun sürerse, zaman bilgisini sohbet komut iletisine ekle"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4117,7 +4221,8 @@ msgstr ""
 "Genellikle bu yalnızca çekirdek/yerleşik katkıda bulunanlar için gereklidir"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "Kayıt sırasında sohbet komutlarını belgele."
 
 #: src/settings_translation_file.cpp
@@ -4209,7 +4314,7 @@ msgid "Joystick button repetition interval"
 msgstr "Joystick düğmesi tekrarlama aralığı"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "Joystick ölü bölgesi"
 
 #: src/settings_translation_file.cpp
@@ -5321,8 +5426,8 @@ msgstr "Harita kaydetme aralığı"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
-msgstr "Sıvı güncelleme tıkı"
+msgid "Map shadows update frames"
+msgstr "Harita güncelleme zamanı"
 
 #: src/settings_translation_file.cpp
 msgid "Mapblock limit"
@@ -5434,7 +5539,7 @@ msgstr "Pencere odaklanmadığında veya oyun duraklatıldığında en yüksek F
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "Gölgeleri işlemek için azami mesafe."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5564,19 +5669,20 @@ msgstr ""
 "Kuyruğa almayı kapamak için 0 ve sınırsız kuyruk boyutu için -1."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Maximum time a file download (e.g. a mod download) may take, stated in "
 "milliseconds."
 msgstr ""
-"Bir dosya indirmesinin ms cinsinden alabileceği maksimum zaman (ör: mod "
-"indirme)."
+"Bir dosya indirmesinin (ör: mod indirme) alabileceği azami süre, milisaniye "
+"cinsinden belirtilir."
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
 msgstr ""
+"Etkileşimli bir isteğin (ör: sunucu listesi getirme) alabileceği azami süre, "
+"milisaniye cinsinden belirtilir."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5639,8 +5745,8 @@ msgid "Mod channels"
 msgstr "Mod kanalları"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr "Hudbar öğelerinin boyutunu değiştirir."
+msgid "Modifies the size of the HUD elements."
+msgstr "HUD ögelerinin boyutunu değiştirir."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
@@ -5650,6 +5756,11 @@ msgstr "Eş aralıklı yazı tipi konumu"
 msgid "Monospace font size"
 msgstr "Eş aralıklı yazı tipi boyutu"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "Eş aralıklı yazı tipi boyutu"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "Dağ yükseklik gürültüsü"
@@ -5792,9 +5903,10 @@ msgstr ""
 "Birçok kullanıcı için en iyi ayar '1' olabilir."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "/clearobjects tarafında tek seferde yüklenebilecek ek blokların sayısı.\n"
@@ -5803,7 +5915,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
-msgstr "Çevrimiçi İçerik Deposu"
+msgstr "Çevrim İçi İçerik Deposu"
 
 #: src/settings_translation_file.cpp
 msgid "Opaque liquids"
@@ -5826,10 +5938,13 @@ msgstr ""
 "duraklamaz."
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5860,10 +5975,9 @@ msgid "Path to texture directory. All textures are first searched from here."
 msgstr "Doku dizini konumu. Tüm dokular ilk burada aranır."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "Öntanımlı yazı tipi konumu.\n"
@@ -5872,10 +5986,9 @@ msgstr ""
 "Yazı tipi yüklenemiyorsa yedek yazı tipi kullanılır."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "Eş aralıklı yazı tipi konumu.\n"
@@ -5936,9 +6049,8 @@ msgid "Player versus player"
 msgstr "Oyuncu oyuncuya karşı"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Bilineer filtreleme"
+msgstr "Poisson filtreleme"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5991,11 +6103,12 @@ msgid "Prometheus listener address"
 msgstr "Prometheus dinleyici adresi"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Prometheus dinleyici adresi.\n"
 "Minetest ENABLE_PROMETHEUS seçeneği etkin olarak derlenmişse,\n"
@@ -6338,37 +6451,40 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
+"Gölge gücünü ayarla.\n"
+"Daha düşük değer daha açık gölgeler, daha yüksek değer daha koyu gölgeler "
+"anlamına gelir."
 
 #: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
-#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"Yumuşak gölge yarıçapı boyutunu ayarla.\n"
+"Daha düşük değerler daha keskin, daha büyük değerler daha yumuşak gölgeler "
+"anlamına gelir.\n"
+"En düşük değer 1.0 ve en yüksek değer 10.0"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"Güneş/Ay yörüngesinin eğimini derece olarak ayarla\n"
+"0 değeri, eğim / dikey yörünge olmadığı anlamına gelir.\n"
+"En düşük değer 0.0 ve en yüksek değer 60.0"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Set to true to enable Shadow Mapping.\n"
 "Requires shaders to be enabled."
 msgstr ""
-"Dalgalanan yaprakları için doğru'ya ayarlayın.\n"
-"Gölgelemeler etkin kılınmalıdır."
+"Gölge Eşlemeyi etkinleştirmek için doğru olarak ayarlayın.\n"
+"Gölgelemelerin etkinleştirilmesini gerektirir."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6400,6 +6516,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"Gölge dokusu kalitesini 32 bit olarak ayarlar.\n"
+"Yanlış ise 16 bit doku kullanılacaktır.\n"
+"Bu, gölgede çok daha fazla bozulmalara neden olabilir."
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6418,22 +6537,20 @@ msgstr ""
 "Bu yalnızca OpenGL video arka ucu ile çalışır."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Ekran yakalama kalitesi"
+msgstr "Gölge filtresi kalitesi"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "Gölgeleri işlemek için nodlardaki gölge eşleme azami mesafesi"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "32 bitte gölge eşleme dokusu"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow map texture size"
-msgstr "Minimum doku boyutu"
+msgstr "Gölge eşleme dokusu boyutu"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6444,7 +6561,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "Gölge gücü"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6467,7 +6584,8 @@ msgstr ""
 "Bunu değiştirdikten sonra yeniden başlatma gerekir."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+#, fuzzy
+msgid "Show name tag backgrounds by default"
 msgstr "Ad etiketi arka planlarını öntanımlı olarak göster"
 
 #: src/settings_translation_file.cpp
@@ -6502,7 +6620,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "Gökyüzü Gövdesi Yörünge Eğimi"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6562,9 +6680,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr "Sızma hızı, saniye başına nod cinsinden."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Yazı tipi gölge saydamlığı"
+msgstr "Yumuşak gölge yarıçapı"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -6592,6 +6709,14 @@ msgstr ""
 "Modların veya oyunların belirli (veya tüm) ögeler için açıkça bir yığın "
 "ayarlayabileceğini unutmayın."
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6723,11 +6848,16 @@ msgid "Texture path"
 msgstr "Doku konumu"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"Gölge eşlemenin işleneceği doku boyutu.\n"
+"Bu, 2'nin bir kuvveti olmalıdır.\n"
+"Daha büyük sayılar daha iyi gölgeler oluşturur ama aynı zamanda daha fazla "
+"kaynak kullanır."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6750,8 +6880,8 @@ msgid "The URL for the content repository"
 msgstr "İçerik deposu için URL"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
-msgstr "Joystick ölü bölgesi"
+msgid "The dead zone of the joystick"
+msgstr "Joystick'in ölü bölgesi"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6825,7 +6955,6 @@ msgstr ""
 "Bu active_object_send_range_blocks ile birlikte ayarlanmalıdır."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "The rendering back-end.\n"
 "A restart is required after changing this.\n"
@@ -6834,7 +6963,7 @@ msgid ""
 "On other platforms, OpenGL is recommended.\n"
 "Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
 msgstr ""
-"Irrlicht için işleme arka ucu.\n"
+"İşleme arka ucu.\n"
 "Bunu değiştirdikten sonra yeniden başlatma gerekir.\n"
 "Not: Android'de, emin değilseniz OGLES1 kullanın! Başka türlü, uygulama "
 "başlayamayabilir.\n"
@@ -6843,9 +6972,10 @@ msgstr ""
 "desteklenmektedir"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "Oyun-içi görünüm frustum'unu hareket ettirirken\n"
 "joystick eksenlerinin hassasiyeti."
@@ -6969,6 +7099,10 @@ msgstr "İpucu gecikmesi"
 msgid "Touch screen threshold"
 msgstr "Dokunmatik ekran eşiği"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "Ağaçlar gürültüsü"
@@ -6993,7 +7127,7 @@ msgstr "Güvenilen modlar"
 
 #: src/settings_translation_file.cpp
 msgid "URL to the server list displayed in the Multiplayer Tab."
-msgstr "Multiplayer sekmesinde görüntülenen sunucu listesi URL'si."
+msgstr "Çok oyunculu sekmesinde görüntülenen sunucu listesinin URL'si."
 
 #: src/settings_translation_file.cpp
 msgid "Undersampling"
@@ -7046,8 +7180,9 @@ msgid "Use bilinear filtering when scaling textures."
 msgstr "Dokuları boyutlandırırken bilineer filtreleme kullan."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7175,9 +7310,8 @@ msgid "Viewing range"
 msgstr "Görüntüleme uzaklığı"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Virtual joystick triggers Aux1 button"
-msgstr "Sanal joystick aux düğmesini tetikler"
+msgstr "Sanal joystick Aux1 düğmesini tetikler"
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
@@ -7254,6 +7388,10 @@ msgstr "Dalgalanan sıvılar dalga-boyu"
 msgid "Waving plants"
 msgstr "Dalgalanan bitkiler"
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Web bağlantısı rengi"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7283,7 +7421,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7294,27 +7432,16 @@ msgstr ""
 "pikselleri\n"
 "korumak için kendiliğinden büyütme yapılır. Bu minimum doku boyutunu\n"
 "büyütülmüş dokular için ayarlar; daha yüksek değerler daha net görünür,\n"
-"ama daha fazla bellek gerektirir. 2'nin kuvvetleri tavsiye edilir. 1'den "
-"daha\n"
-"yükseğe ayarlamanın, bilineer/trilineer/anisotropik filtreler etkin "
-"değilse,\n"
-"görünür bit etkisi olmayabilir.\n"
-"Bu, dünya hizalı doku kendilinden boyutlandırmada taban nod doku boyutu\n"
+"ama daha fazla bellek gerektirir. 2'nin kuvvetleri tavsiye edilir. Bu ayar "
+"YALNIZCA\n"
+"bilineer/trilineer/anisotropik filtreler etkinse uygulanır.\n"
+"Bu, dünya hizalı doku kendiliğinden boyutlandırmada taban nod doku boyutu\n"
 "olarak da kullanılır."
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-"Freetype yazı tiplerinin kullanılıp kullanılmayacağını, freetype desteği ile "
-"derlenmiş olmalıdır.\n"
-"Devre dışı kılınırsa, yerine bitmap ve XML vektör yazı tipleri kullanılır."
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 "Ad etiketi arka planlarının öntanımlı olarak gösterilip gösterilmeyileceği.\n"
@@ -7375,9 +7502,9 @@ msgstr ""
 "ile aynı etkiye sahiptir)."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Width component of the initial window size. Ignored in fullscreen mode."
-msgstr "İlk pencere boyutunun genişlik bileşeni."
+msgstr ""
+"İlk pencere boyutunun genişlik bileşeni. Tam ekran kipinde yok sayılır."
 
 #: src/settings_translation_file.cpp
 msgid "Width of the selection box lines around nodes."
@@ -7477,48 +7604,24 @@ msgstr "Daha alt arazinin ve göl yatağının Y-seviyesi."
 msgid "Y-level of seabed."
 msgstr "Deniz yatağının Y-seviyesi."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Harita kütlerini diske kaydederken kullanılacak ZLib sıkıştırma düzeyi.\n"
-"-1 - Zlib'in varsayılan sıkıştırma düzeyi\n"
-"0 - hiçbir sıkıştırma yok, en hızlı\n"
-"9 - en iyi sıkıştırma, en yavaş\n"
-"(seviye 1-3, Zlib'in \"hızlı\" , 4-9 sıradan yöntemi kullanır)"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-"Harita kütlerini istemciye(client) gönderirken kullanılacak ZLib sıkıştırma "
-"düzeyi.\n"
-"-1 - Zlib'in varsayılan sıkıştırma düzeyi\n"
-"0 - hiçbir sıkıştırma yok, en hızlı\n"
-"9 - en iyi sıkıştırma, en yavaş\n"
-"(seviye 1-3, Zlib'in \"hızlı\" , 4-9 sıradan yöntemi kullanır)"
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL dosya indirme zaman aşımı"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "cURL interactive timeout"
-msgstr "cURL zaman aşımı"
+msgstr "cURL etkileşimli zaman aşımı"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr "cURL paralel sınırı"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Yaratıcı Kip: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Hasar: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7700,6 +7803,9 @@ msgstr "cURL paralel sınırı"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "Yedek yazı tipinin nokta (pt) olarak boyutu."
 
+#~ msgid "FreeType fonts"
+#~ msgstr "Freetype yazı tipleri"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "Tam ekran BPP"
 
@@ -7718,6 +7824,9 @@ msgstr "cURL paralel sınırı"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 desteği."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Kur: dosya: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Lav derinliği"
 
@@ -7823,6 +7932,17 @@ msgstr "cURL paralel sınırı"
 #~ msgid "Select Package File:"
 #~ msgstr "Paket Dosyası Seç:"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "Gölge güncelleme zamanını ayarla.\n"
+#~ "Daha düşük değer, gölgeler ve harita güncellemelerinin daha hızlı olması "
+#~ "anlamına gelir, ancak daha fazla kaynak tüketir.\n"
+#~ "En düşük değer 0,001 saniye, en yüksek değer 0,2 saniyedir"
+
 #~ msgid "Shadow limit"
 #~ msgstr "Gölge sınırı"
 
@@ -7850,6 +7970,9 @@ msgstr "cURL paralel sınırı"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "Belirli diller için bu yazı tipi kullanılacak."
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "OpenGL sürücüleri seçilmeden gölgelemeler etkinleştirilemez."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Sinematik Aç/Kapa"
 
@@ -7872,6 +7995,15 @@ msgstr "cURL paralel sınırı"
 #~ msgid "Waving water"
 #~ msgstr "Dalgalanan su"
 
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr ""
+#~ "Freetype yazı tiplerinin kullanılıp kullanılmayacağını, freetype desteği "
+#~ "ile derlenmiş olmalıdır.\n"
+#~ "Devre dışı kılınırsa, yerine bitmap ve XML vektör yazı tipleri kullanılır."
+
 #~ msgid "Whether dungeons occasionally project from the terrain."
 #~ msgstr "Zindanların bazen araziden yansıyıp yansımayacağı."
 
@@ -7887,5 +8019,8 @@ msgstr "cURL paralel sınırı"
 #~ msgid "Yes"
 #~ msgstr "Evet"
 
+#~ msgid "You died."
+#~ msgstr "Öldün."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 2064907ffdb0fce71a85926e8aee9e49f516e319..8820322320a49475dcc7c23ea939f1917fec7453 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: minetest\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
 "PO-Revision-Date: 2021-04-08 18:26+0000\n"
 "Last-Translator: Timur Seber <seber.tatsoft@gmail.com>\n"
 "Language-Team: Tatar <https://hosted.weblate.org/projects/minetest/minetest/"
@@ -63,11 +63,6 @@ msgstr "Тергезелергә"
 msgid "You died"
 msgstr "Сез үлдегез"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Сез үлдегез"
-
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
 msgstr ""
@@ -97,6 +92,10 @@ msgstr ""
 msgid "OK"
 msgstr "Ярый"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr ""
@@ -295,6 +294,10 @@ msgstr ""
 msgid "Install missing dependencies"
 msgstr ""
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -620,7 +623,7 @@ msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -730,14 +733,6 @@ msgstr ""
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr ""
@@ -1101,10 +1096,6 @@ msgstr ""
 msgid "Texturing:"
 msgstr ""
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr ""
@@ -1137,7 +1128,7 @@ msgstr ""
 msgid "Waving Plants"
 msgstr ""
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr ""
 
@@ -1166,7 +1157,7 @@ msgid "Connection error (timed out?)"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
+msgid "Could not find or load game"
 msgstr ""
 
 #: src/client/clientlauncher.cpp
@@ -1207,14 +1198,6 @@ msgstr ""
 msgid "- Address: "
 msgstr ""
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr ""
@@ -1236,6 +1219,15 @@ msgstr ""
 msgid "- Server Name: "
 msgstr ""
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr ""
@@ -1244,6 +1236,22 @@ msgstr ""
 msgid "Automatic forward enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr ""
@@ -1252,6 +1260,10 @@ msgstr ""
 msgid "Camera update enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr ""
@@ -1264,6 +1276,10 @@ msgstr ""
 msgid "Cinematic mode enabled"
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr ""
@@ -1272,6 +1288,10 @@ msgstr ""
 msgid "Connecting to server..."
 msgstr ""
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr ""
@@ -1295,6 +1315,11 @@ msgid ""
 "- %s: chat\n"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr ""
@@ -1487,6 +1512,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1821,6 +1861,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2016,7 +2064,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2223,6 +2272,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2489,6 +2542,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2522,7 +2579,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2541,6 +2598,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2616,6 +2679,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2707,7 +2786,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2784,8 +2863,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2903,6 +2982,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2949,7 +3032,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2977,13 +3067,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3068,6 +3151,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3252,11 +3341,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3265,6 +3358,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3324,10 +3428,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3376,7 +3476,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3808,7 +3908,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3892,7 +3992,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4721,7 +4821,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5014,7 +5114,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5025,6 +5125,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5146,7 +5250,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5170,11 +5274,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5197,17 +5303,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5310,9 +5412,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5605,26 +5707,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5715,7 +5809,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5820,6 +5914,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5930,7 +6032,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5948,7 +6050,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6017,7 +6119,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6110,6 +6212,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6180,7 +6286,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6363,6 +6469,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6384,7 +6494,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6392,14 +6502,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6525,24 +6628,6 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6554,3 +6639,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
 msgstr ""
+
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Сез үлдегез"
index f36fddc273aeea75ad7f7ece1eacaf8903726bc8..aa29280992611161d81c38728b3ac3ef3b5ff365 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Ukrainian (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-06-07 14:33+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-30 18:51+0000\n"
 "Last-Translator: Andrij Mizyk <andmizyk@gmail.com>\n"
 "Language-Team: Ukrainian <https://hosted.weblate.org/projects/minetest/"
 "minetest/uk/>\n"
@@ -13,40 +13,35 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Очистити чергу чату"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "Ð\9aоманди Ñ\87аÑ\82Ñ\83"
+msgstr "Ð\9fоÑ\80ожнÑ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Вихід в меню"
+msgstr "Ð\92иÑ\85Ñ\96д Ð² Ð¾Ñ\81новне Ð¼ÐµÐ½Ñ\8e"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "Ð\9aоманда (локалÑ\8cна)"
+msgstr "Ð\9dепÑ\80авилÑ\8cна ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Проблемна команда: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "Ð\9eдиноÑ\87на Ð³Ñ\80а"
+msgstr "СпиÑ\81ок Ð³Ñ\80авÑ\86Ñ\96в Ñ\83 Ð¼ÐµÑ\80ежÑ\96"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "Ð\9eдиноÑ\87на Ð³Ñ\80а"
+msgstr "Ð\93Ñ\80авÑ\86Ñ\96 Ð² Ð¼ÐµÑ\80ежÑ\96"
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
@@ -54,7 +49,7 @@ msgstr ""
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Ця команда вимкнена на сервері."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,28 +59,21 @@ msgstr "Переродитися"
 msgid "You died"
 msgstr "Ви загинули"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Ви загинули"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "Ð\9aоманда (локалÑ\8cна)"
+msgstr "Ð\94оÑ\81Ñ\82Ñ\83пнÑ\96 ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "Ð\9aоманда (локалÑ\8cна)"
+msgstr "Ð\94оÑ\81Ñ\82Ñ\83пнÑ\96 ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Команда не доступна: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Отримати довідку для команд"
 
 #: builtin/common/chatcommands.lua
 msgid ""
@@ -98,11 +86,15 @@ msgstr ""
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
-msgstr "ОК"
+msgstr "Добре"
+
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
-msgstr "Трапилася помилка у скрипті Lua:"
+msgstr "Трапилася помилка в скрипті Lua:"
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred:"
@@ -110,11 +102,11 @@ msgstr "Трапилася помилка:"
 
 #: builtin/fstk/ui.lua
 msgid "Main menu"
-msgstr "Ð\93оловне меню"
+msgstr "Ð\9eÑ\81новне меню"
 
 #: builtin/fstk/ui.lua
 msgid "Reconnect"
-msgstr "Ð\9fеÑ\80епÑ\96дклÑ\8eÑ\87ення"
+msgstr "Ð\9fеÑ\80езʼÑ\94днання"
 
 #: builtin/fstk/ui.lua
 msgid "The server has requested a reconnect:"
@@ -302,6 +294,10 @@ msgstr "Встановити $1"
 msgid "Install missing dependencies"
 msgstr "Встановити відсутні залежності"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Установлення: Непідтримуваний тип файлу або пошкоджений архів"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -630,7 +626,7 @@ msgid "Offset"
 msgstr "Зсув"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+msgid "Persistence"
 msgstr "Постійність"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -741,14 +737,6 @@ msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr ""
 "Встановлення мода: неможливо знайти відповідну назву теки для пакмоду $1"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "Встановлення: тип файлу \"$1\" не підтримується або архів пошкоджено"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "Встановлення: файл: \"$1\""
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "Неможливо знайти правильний мод або пакмод"
@@ -785,24 +773,23 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Про"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
-msgstr "Ð\90кÑ\82ивнÑ\96 Ñ\83Ñ\87аÑ\81ники"
+msgstr "Ð\90кÑ\82ивнÑ\96 Ñ\81пÑ\96вÑ\80озÑ\80обники"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "Ð\94Ñ\96апазон Ð²Ñ\96дпÑ\80авленнÑ\8f Ð°ÐºÑ\82ивниÑ\85 Ð±Ð»Ð¾ÐºÑ\96в"
+msgstr "Ð\90кÑ\82ивний Ð¿Ñ\80омалÑ\8cовÑ\83ваÑ\87:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
-msgstr "РозÑ\80обники Ñ\8fдÑ\80а"
+msgstr "Ð\9eÑ\81новнÑ\96 Ñ\80озÑ\80обники"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Open User Data Directory"
-msgstr "Відкрийте каталог користувацьких даних"
+msgstr "Відкрити каталог користувацьких даних"
 
 #: builtin/mainmenu/tab_about.lua
 msgid ""
@@ -814,19 +801,19 @@ msgstr ""
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
-msgstr "Ð\9fопеÑ\80еднÑ\96 Ñ\83Ñ\87аÑ\81ники"
+msgstr "Ð\9fопеÑ\80еднÑ\96 Ñ\81пÑ\96вÑ\80озÑ\80обники"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Core Developers"
-msgstr "Попередні розробники ядра"
+msgstr "Попередні основні розробники"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Browse online content"
-msgstr "Ð\9fеÑ\80еглÑ\8fнÑ\83Ñ\82и ÐºÐ¾Ð½Ñ\82ент у мережі"
+msgstr "Ð\9eглÑ\8fнÑ\83Ñ\82и Ð²Ð¼Ñ\96Ñ\81т у мережі"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Content"
-msgstr "Ð\9aонÑ\82ент"
+msgstr "Ð\92мÑ\96Ñ\81т"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Disable Texture Pack"
@@ -858,11 +845,11 @@ msgstr "Видалити пакунок"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Use Texture Pack"
-msgstr "УвÑ\96мкнÑ\83Ñ\82и набір текстур"
+msgstr "Ð\92икоÑ\80. набір текстур"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Announce Server"
-msgstr "Ð\9fÑ\83блÑ\96Ñ\87ний"
+msgstr "Ð\90нонÑ\81Ñ\83ваÑ\82и Ñ\81еÑ\80веÑ\80"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Bind Address"
@@ -870,11 +857,11 @@ msgstr "Закріпити адресу"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Creative Mode"
-msgstr "Творчій режим"
+msgstr "Творчий режим"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Enable Damage"
-msgstr "УвÑ\96мкнÑ\83Ñ\82и Ñ\83шкодження"
+msgstr "Ð\94озволиÑ\82и Ð¿Ð¾шкодження"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Game"
@@ -906,7 +893,7 @@ msgstr "Пароль"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
-msgstr "Грати"
+msgstr "Грати гру"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Port"
@@ -929,9 +916,8 @@ msgid "Start Game"
 msgstr "Почати гру"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- Адреса: "
+msgstr "Адреса"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -939,50 +925,46 @@ msgstr "Очистити"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Connect"
-msgstr "Ð\9fÑ\96д'єднатися"
+msgstr "Ð\97ʼєднатися"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Creative mode"
-msgstr "Творчій режим"
+msgstr "Творчий режим"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "Ð\9fоÑ\80аненнÑ\8f"
+msgstr "Ð\9fоÑ\88кодженнÑ\8f / Ð\93пÐ\93"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
-msgstr "Видалити з закладок"
+msgstr "Видалити зі закладок"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "Ð\97акладки"
+msgstr "Ð\92Ñ\96дÑ\96бÑ\80анÑ\96"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Несумісні сервери"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
-msgstr "Ð\9fÑ\96д'Ñ\94днатися до гри"
+msgstr "Ð\94олÑ\83Ñ\87итися до гри"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Ping"
-msgstr "Пінг"
+msgstr "Пінґ"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "Публічний"
+msgstr "Публічні сервери"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Оновити"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "Опис сервера"
 
@@ -1004,7 +986,7 @@ msgstr "8x"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "All Settings"
-msgstr "Ð\92сі налаштування"
+msgstr "Усі налаштування"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Antialiasing:"
@@ -1016,7 +998,7 @@ msgstr "Зберігати розмір вікна"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Bilinear Filter"
-msgstr "Ð\91Ñ\96лÑ\96нÑ\96йна Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80аÑ\86Ñ\96я"
+msgstr "Ð\94волÑ\96нÑ\96йне Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80Ñ\83вання"
 
 #: builtin/mainmenu/tab_settings.lua src/client/game.cpp
 msgid "Change Keys"
@@ -1024,15 +1006,15 @@ msgstr "Змінити клавіші"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Connected Glass"
-msgstr "З'єднане скло"
+msgstr "Зʼєднане скло"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "Динамічні тіні"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Динамічні тіні: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1060,7 +1042,7 @@ msgstr "Міпмапи і анізотропний фільтр"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "No Filter"
-msgstr "Без фільтрації"
+msgstr "Без фільтрування"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "No Mipmap"
@@ -1100,7 +1082,7 @@ msgstr "Налаштування"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Shaders"
-msgstr "ШейдеÑ\80и"
+msgstr "Ð\92Ñ\96дÑ\82Ñ\96нÑ\8eваÑ\87Ñ\96"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (experimental)"
@@ -1108,7 +1090,7 @@ msgstr "Відтінювачі (експериментальне)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
-msgstr "ШейдеÑ\80и (недоступно)"
+msgstr "Ð\92Ñ\96дÑ\82Ñ\96нÑ\8eваÑ\87Ñ\96 (недоступно)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Simple Leaves"
@@ -1122,10 +1104,6 @@ msgstr "Згладжене освітлення"
 msgid "Texturing:"
 msgstr "Текстурування:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "Для того, щоб увімкнути шейдери, потрібно мати драйвер OpenGL."
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "Тоновий шейдер"
@@ -1158,21 +1136,21 @@ msgstr "Хвилясті Рідини"
 msgid "Waving Plants"
 msgstr "Коливати квіти"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "Час очікування вийшов."
 
 #: src/client/client.cpp
 msgid "Done!"
-msgstr "Ð\92иконано!"
+msgstr "Ð\93оÑ\82ово!"
 
 #: src/client/client.cpp
 msgid "Initializing nodes"
-msgstr "Ініціалізація блоків"
+msgstr "Ініціалізування блоків"
 
 #: src/client/client.cpp
 msgid "Initializing nodes..."
-msgstr "Ініціалізація блоків..."
+msgstr "Ініціалізування блоків..."
 
 #: src/client/client.cpp
 msgid "Loading textures..."
@@ -1184,11 +1162,11 @@ msgstr "Перебудова шейдерів..."
 
 #: src/client/clientlauncher.cpp
 msgid "Connection error (timed out?)"
-msgstr "Помилка з'єднання (час вийшов?)"
+msgstr "Помилка зʼєднання (час вийшов?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "Неможливо знайти або завантажити гру \""
+msgid "Could not find or load game"
+msgstr "Неможливо знайти або завантажити гру"
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1196,7 +1174,7 @@ msgstr "Помилкова конфігурація gamespec."
 
 #: src/client/clientlauncher.cpp
 msgid "Main Menu"
-msgstr "Ð\93оловне Ð\9cеню"
+msgstr "Ð\9eÑ\81новне Ð¼еню"
 
 #: src/client/clientlauncher.cpp
 msgid "No world selected and no address provided. Nothing to do."
@@ -1204,11 +1182,11 @@ msgstr "Жоден світ не вибрано та не надано адре
 
 #: src/client/clientlauncher.cpp
 msgid "Player name too long."
-msgstr "Ім'я гравця занадто довге."
+msgstr "Імʼя гравця задовге."
 
 #: src/client/clientlauncher.cpp
 msgid "Please choose a name!"
-msgstr "Будь-ласка введіть ім'я!"
+msgstr "Будь-ласка, оберіть імʼя!"
 
 #: src/client/clientlauncher.cpp
 msgid "Provided password file failed to open: "
@@ -1230,14 +1208,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- Адреса: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- Творчість: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- Ушкодження: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- Режим: "
@@ -1253,12 +1223,21 @@ msgstr "- Публічний: "
 #. ~ PvP = Player versus Player
 #: src/client/game.cpp
 msgid "- PvP: "
-msgstr "- PvP (бої): "
+msgstr "- ГпГ (бої): "
 
 #: src/client/game.cpp
 msgid "- Server Name: "
 msgstr "- Назва сервера: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Трапилася помилка серіалізації:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Доступ відхилено. Причина: %s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "Автоматичний рух вперед вимкнено"
@@ -1267,6 +1246,22 @@ msgstr "Автоматичний рух вперед вимкнено"
 msgid "Automatic forward enabled"
 msgstr "Автоматичний рух вперед увімкнено"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "Оновлення камери вимкнено"
@@ -1275,6 +1270,10 @@ msgstr "Оновлення камери вимкнено"
 msgid "Camera update enabled"
 msgstr "Оновлення камери увімкнено"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "Змінити пароль"
@@ -1287,6 +1286,10 @@ msgstr "Кінорежим вимкнено"
 msgid "Cinematic mode enabled"
 msgstr "Кінорежим увімкнено"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Клієнта відʼєднано"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "Клієнтосторонні скрипти на клієнті вимкнено"
@@ -1295,6 +1298,10 @@ msgstr "Клієнтосторонні скрипти на клієнті вим
 msgid "Connecting to server..."
 msgstr "Підключення до сервера..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Невдале зʼєднання з невідомих причин"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "Продовжити"
@@ -1328,10 +1335,15 @@ msgstr ""
 "- %s: крастися/лізти вниз\n"
 "- %s: кинути предмет\n"
 "- %s: інвентар\n"
-"- Mouse: поворот/дивитися\n"
-"- Mouse wheel: вибір предмета\n"
+"- Миша: поворот/дивитися\n"
+"- Коліщатко миші: вибір предмета\n"
 "- %s: чат\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "Створення клієнта..."
@@ -1390,11 +1402,11 @@ msgstr "Необмежена видимість (повільно)"
 
 #: src/client/game.cpp
 msgid "Exit to Menu"
-msgstr "Вихід в меню"
+msgstr "Вихід у меню"
 
 #: src/client/game.cpp
 msgid "Exit to OS"
-msgstr "Вихід з гри"
+msgstr "Вихід із гри"
 
 #: src/client/game.cpp
 msgid "Fast mode disabled"
@@ -1461,9 +1473,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "Мінімапа вимкнена грою або модифікацією"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "Ð\9eдиноÑ\87на гра"
+msgstr "Ð\91агаÑ\82окоÑ\80иÑ\81Ñ\82Ñ\83ваÑ\86Ñ\8cка гра"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1483,11 +1494,11 @@ msgstr "Визначення блоків..."
 
 #: src/client/game.cpp
 msgid "Off"
-msgstr "Вимкнено"
+msgstr "Вимк."
 
 #: src/client/game.cpp
 msgid "On"
-msgstr "Увімкнено"
+msgstr "Увім."
 
 #: src/client/game.cpp
 msgid "Pitch move mode disabled"
@@ -1537,6 +1548,21 @@ msgstr "Звукова система не підтримується у цій
 msgid "Sound unmuted"
 msgstr "Звук увімкнено"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1567,23 +1593,23 @@ msgstr "Наближення (бінокль) вимкнено грою або 
 
 #: src/client/game.cpp
 msgid "ok"
-msgstr "гаÑ\80азд"
+msgstr "добÑ\80е"
 
 #: src/client/gameui.cpp
 msgid "Chat hidden"
-msgstr "Чат вимкнено"
+msgstr "Чат сховано"
 
 #: src/client/gameui.cpp
 msgid "Chat shown"
-msgstr "Чат увімкнено"
+msgstr "Чат показано"
 
 #: src/client/gameui.cpp
 msgid "HUD hidden"
-msgstr "Позначки на екрані вимкнено"
+msgstr "HUD приховано"
 
 #: src/client/gameui.cpp
 msgid "HUD shown"
-msgstr "Позначки на екрані увімкнено"
+msgstr "HUD показано"
 
 #: src/client/gameui.cpp
 msgid "Profiler hidden"
@@ -1600,7 +1626,7 @@ msgstr "Додатки"
 
 #: src/client/keycode.cpp
 msgid "Backspace"
-msgstr "Назад (Backspace)"
+msgstr "Backspace"
 
 #: src/client/keycode.cpp
 msgid "Caps Lock"
@@ -1628,7 +1654,7 @@ msgstr "Виконати"
 
 #: src/client/keycode.cpp
 msgid "Help"
-msgstr "Ð\94опомога"
+msgstr "Ð\94овÑ\96дка"
 
 #: src/client/keycode.cpp
 msgid "Home"
@@ -1815,7 +1841,7 @@ msgstr "Scroll Lock"
 #. ~ Key name
 #: src/client/keycode.cpp
 msgid "Select"
-msgstr "Ð\9eбрати"
+msgstr "Ð\92ибрати"
 
 #: src/client/keycode.cpp
 msgid "Shift"
@@ -1827,7 +1853,7 @@ msgstr "Сон"
 
 #: src/client/keycode.cpp
 msgid "Snapshot"
-msgstr "Знімок"
+msgstr "Зріз"
 
 #: src/client/keycode.cpp
 msgid "Space"
@@ -1868,9 +1894,16 @@ msgid "Minimap in surface mode, Zoom x%d"
 msgstr "Мінімапа в режимі поверхні. Наближення x%d"
 
 #: src/client/minimap.cpp
-#, fuzzy
 msgid "Minimap in texture mode"
-msgstr "Мінімапа в режимі поверхня. Наближення х1"
+msgstr "Мінімапа в текстурному режимі"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "Не вдалося завантажити вебсторінку"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "Відкривання вебсторінки"
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
@@ -1900,9 +1933,8 @@ msgid "Proceed"
 msgstr "Далі"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "Спеціальна = спускатися"
+msgstr "\"Aux1\" = лізти вниз"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1914,7 +1946,7 @@ msgstr "Автоматичне перестрибування"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1988,7 +2020,7 @@ msgstr ""
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Local command"
-msgstr "Ð\9aоманда (локалÑ\8cна)"
+msgstr "Ð\9bокалÑ\8cна ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Mute"
@@ -1996,11 +2028,11 @@ msgstr "Вимкнути звук"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Next item"
-msgstr "Наступний слот"
+msgstr "Наступний предмет"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Prev. item"
-msgstr "Попередній слот"
+msgstr "Попередній предмет"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Range select"
@@ -2008,7 +2040,7 @@ msgstr "Вибір діапазону"
 
 #: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
 msgid "Screenshot"
-msgstr "Знімок екрану"
+msgstr "Знімок екрана"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Sneak"
@@ -2016,11 +2048,11 @@ msgstr "Крастися"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle HUD"
-msgstr "Увімкнути позначки на екрані"
+msgstr "Увімкнути HUD"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle chat log"
-msgstr "Увімкнути чат (журнал)"
+msgstr "Увімкнути журнал чату"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Toggle fast"
@@ -2048,7 +2080,7 @@ msgstr "Увімкнути висотний рух"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "press key"
-msgstr "вибеÑ\80Ñ\96Ñ\82Ñ\8c"
+msgstr "наÑ\82иÑ\81нÑ\96Ñ\82Ñ\8c ÐºÐ»Ð°Ð²Ñ\96Ñ\88Ñ\83"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Change"
@@ -2056,7 +2088,7 @@ msgstr "Змінити"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "Confirm Password"
-msgstr "Підтвердити новий пароль"
+msgstr "Підтвердіть пароль"
 
 #: src/gui/guiPasswordChange.cpp
 msgid "New Password"
@@ -2075,8 +2107,9 @@ msgid "Muted"
 msgstr "Звук вимкнено"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "Гучність звуку: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "Гучність звуку: %d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2101,16 +2134,15 @@ msgstr ""
 "дотику."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(Android) Використовувати віртуальний джойстик для активації кнопки \"aux"
-"\".\n"
-"Якщо увімкнено, віртуальний джойстик також натисне \"aux\", коли поза межами "
-"головного кола."
+"(Android) Використовувати віртуальний джойстик для активації кнопки \"Aux1\"."
+"\n"
+"Якщо ввімкнено, віртуальний джойстик також натисне \"Aux1\", коли поза "
+"межами Ð³Ð¾Ð»Ð¾Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ¾Ð»Ð°."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2180,7 +2212,7 @@ msgstr "2D шум що розміщує долини та русла річок.
 
 #: src/settings_translation_file.cpp
 msgid "3D clouds"
-msgstr "Об'ємні хмари"
+msgstr "Обʼємні хмари"
 
 #: src/settings_translation_file.cpp
 msgid "3D mode"
@@ -2286,7 +2318,7 @@ msgstr "Абсолютний ліміт відображення блоків з
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration in air"
-msgstr "Прискорення у повітрі"
+msgstr "Прискорення в повітрі"
 
 #: src/settings_translation_file.cpp
 msgid "Acceleration of gravity, in nodes per second per second."
@@ -2330,6 +2362,10 @@ msgstr ""
 "Налаштувати dpi на вашому екрані (тільки не X11/Android), напр. для 4k-"
 "екранів."
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2437,7 +2473,6 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatic forward key"
 msgstr "Клавіша автоматичного руху вперед"
 
@@ -2458,18 +2493,16 @@ msgid "Autoscaling mode"
 msgstr "Режим автомасштабування"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "СÑ\82Ñ\80ибок"
+msgstr "Ð\9aлавÑ\96Ñ\88а Aux1"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "СпеÑ\86Ñ\96алÑ\8cна ÐºÐ»Ð°Ð²Ñ\96Ñ\88а Ð´Ð»Ñ\8f Ñ\80Ñ\83Ñ\85Ñ\83 Ð²Ð³Ð¾Ñ\80Ñ\83/вниз"
+msgstr "Ð\9aлавÑ\96Ñ\88а Aux1 Ð´Ð»Ñ\8f Ð¿Ñ\96днÑ\96маннÑ\8f\81пÑ\83Ñ\81кÑ\83"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
-msgstr "Назад"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ð\9dазад"
 
 #: src/settings_translation_file.cpp
 msgid "Base ground level"
@@ -2613,6 +2646,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "Команди чату"
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr "Розмір шрифту чату"
@@ -2643,11 +2680,11 @@ msgstr "Максимальна довжина повідомлення чату"
 
 #: src/settings_translation_file.cpp
 msgid "Chat toggle key"
-msgstr "ЧаÑ\82"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ñ\83вÑ\96мкненнÑ\8f Ñ\87аÑ\82Ñ\83"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "Ð\9aоманди чату"
+msgid "Chat weblinks"
+msgstr "Ð\92ебпоÑ\81иланнÑ\8f чату"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2659,12 +2696,18 @@ msgstr "Кінорежим"
 
 #: src/settings_translation_file.cpp
 msgid "Cinematic mode key"
-msgstr "Кінорежим"
+msgstr "Клавіша кінорежиму"
 
 #: src/settings_translation_file.cpp
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "Клієнт"
@@ -2710,9 +2753,8 @@ msgid "Colored fog"
 msgstr "Кольоровий туман"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "Кольоровий туман"
+msgstr "Кольорові тіні"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2739,7 +2781,23 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Command key"
-msgstr "Команда"
+msgstr "Клавіша команди"
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
@@ -2774,9 +2832,8 @@ msgid "ContentDB Max Concurrent Downloads"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "ContentDB URL"
-msgstr "Додатки"
+msgstr "URL ContentDB"
 
 #: src/settings_translation_file.cpp
 msgid "Continuous forward"
@@ -2820,7 +2877,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
-msgstr ""
+msgstr "Повідомлення збою"
 
 #: src/settings_translation_file.cpp
 msgid "Creative"
@@ -2833,7 +2890,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2856,7 +2913,7 @@ msgstr "Поранення"
 
 #: src/settings_translation_file.cpp
 msgid "Debug info toggle key"
-msgstr ""
+msgstr "Клавіша увімкнення даних налагодження"
 
 #: src/settings_translation_file.cpp
 msgid "Debug log file size threshold"
@@ -2864,11 +2921,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Debug log level"
-msgstr ""
+msgstr "Рівень журналу зневадження"
 
 #: src/settings_translation_file.cpp
 msgid "Dec. volume key"
-msgstr ""
+msgstr "Клавіша зменш. гучності"
 
 #: src/settings_translation_file.cpp
 msgid "Decrease this to increase liquid resistance to movement."
@@ -2904,17 +2961,16 @@ msgstr "Стандартні права"
 
 #: src/settings_translation_file.cpp
 msgid "Default report format"
-msgstr ""
+msgstr "Типовий формат звіту"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Default stack size"
-msgstr "СÑ\82андаÑ\80Ñ\82на Ð³Ñ\80а"
+msgstr "Типовий Ñ\80озмÑ\96Ñ\80 Ñ\81Ñ\82екÑ\83"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -3017,9 +3073,8 @@ msgid "Desynchronize block animation"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dig key"
-msgstr "Ð\9fÑ\80ава ÐºÐ»Ð°Ð²Ñ\96Ñ\88а"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ð\9aопаÑ\82и"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3033,6 +3088,10 @@ msgstr "Вимкнути античіт"
 msgid "Disallow empty passwords"
 msgstr "Заборонити порожні паролі"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "Доменне ім'я сервера, яке буде показуватися у списку серверів."
@@ -3047,7 +3106,7 @@ msgstr "Подвійне натискання кнопки стрибка вми
 
 #: src/settings_translation_file.cpp
 msgid "Drop item key"
-msgstr "Ð\9aнопка Ð´Ð»Ñ\8f викидання предметів"
+msgstr "Ð\9aлавÑ\96Ñ\88а викидання предметів"
 
 #: src/settings_translation_file.cpp
 msgid "Dump the mapgen debug information."
@@ -3079,17 +3138,24 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
-msgstr ""
+msgstr "Дозволити вікно консолі"
 
 #: src/settings_translation_file.cpp
 msgid "Enable creative mode for all players"
-msgstr ""
+msgstr "Дозволити режим творчості для всіх гравців"
 
 #: src/settings_translation_file.cpp
 msgid "Enable joysticks"
@@ -3107,13 +3173,6 @@ msgstr ""
 msgid "Enable players getting damage and dying."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr ""
@@ -3180,7 +3239,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Enables animation of inventory items."
-msgstr ""
+msgstr "Дозволити анімацію предметів інвентаря."
 
 #: src/settings_translation_file.cpp
 msgid "Enables caching of facedir rotated meshes."
@@ -3198,6 +3257,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3217,9 +3282,8 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "FPS when unfocused or paused"
-msgstr "Максимум FPS при паузі."
+msgstr "FPS, коли призупинено або поза фокусом"
 
 #: src/settings_translation_file.cpp
 msgid "FSAA"
@@ -3234,13 +3298,12 @@ msgid "Fall bobbing factor"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Fallback font path"
-msgstr "Шлях до шрифту"
+msgstr "ШлÑ\8fÑ\85 Ð´Ð¾ Ñ\80езеÑ\80вного Ñ\88Ñ\80иÑ\84Ñ\82Ñ\83"
 
 #: src/settings_translation_file.cpp
 msgid "Fast key"
-msgstr ""
+msgstr "Швидка клавіша"
 
 #: src/settings_translation_file.cpp
 msgid "Fast mode acceleration"
@@ -3248,11 +3311,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Fast mode speed"
-msgstr ""
+msgstr "Швидкість швидкого режиму"
 
 #: src/settings_translation_file.cpp
 msgid "Fast movement"
-msgstr ""
+msgstr "Швидкі рухи"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3345,11 +3408,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Fly key"
-msgstr "Ð\9aнопка Ð´Ð»Ñ\8f польоту"
+msgstr "Ð\9aлавÑ\96Ñ\88а польоту"
 
 #: src/settings_translation_file.cpp
 msgid "Flying"
-msgstr ""
+msgstr "Політ"
 
 #: src/settings_translation_file.cpp
 msgid "Fog"
@@ -3361,34 +3424,38 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Fog toggle key"
-msgstr ""
+msgstr "Клавіша ввімкнення туману"
 
 #: src/settings_translation_file.cpp
 msgid "Font bold by default"
-msgstr ""
+msgstr "Типовий грубий шрифт"
 
 #: src/settings_translation_file.cpp
 msgid "Font italic by default"
-msgstr ""
+msgstr "Типовий похилий шрифт"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow"
-msgstr ""
+msgstr "Тінь шрифту"
 
 #: src/settings_translation_file.cpp
 msgid "Font shadow alpha"
-msgstr ""
+msgstr "Альфа-тінь шрифту"
 
 #: src/settings_translation_file.cpp
 msgid "Font size"
 msgstr "Розмір шрифту"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3397,6 +3464,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3406,7 +3484,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Format of screenshots."
-msgstr ""
+msgstr "Формат знімків екрана."
 
 #: src/settings_translation_file.cpp
 msgid "Formspec Default Background Color"
@@ -3442,7 +3520,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Forward key"
-msgstr "Вперед"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ð\92пеÑ\80ед"
 
 #: src/settings_translation_file.cpp
 msgid "Fourth of 4 2D noises that together define hill/mountain range height."
@@ -3456,10 +3534,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3508,7 +3582,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3549,7 +3623,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "HUD toggle key"
-msgstr ""
+msgstr "Клавіша ввімкнення HUD"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3645,135 +3719,135 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 1 key"
-msgstr ""
+msgstr "Клавіша слоту 1 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 10 key"
-msgstr ""
+msgstr "Клавіша слоту 10 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 11 key"
-msgstr ""
+msgstr "Клавіша слоту 11 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 12 key"
-msgstr ""
+msgstr "Клавіша слоту 12 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 13 key"
-msgstr ""
+msgstr "Клавіша слоту 13 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 14 key"
-msgstr ""
+msgstr "Клавіша слоту 14 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 15 key"
-msgstr ""
+msgstr "Клавіша слоту 15 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 16 key"
-msgstr ""
+msgstr "Клавіша слоту 16 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 17 key"
-msgstr ""
+msgstr "Клавіша слоту 17 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 18 key"
-msgstr ""
+msgstr "Клавіша слоту 18 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 19 key"
-msgstr ""
+msgstr "Клавіша слоту 19 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 2 key"
-msgstr ""
+msgstr "Клавіша слоту 2 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 20 key"
-msgstr ""
+msgstr "Клавіша слоту 20 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 21 key"
-msgstr ""
+msgstr "Клавіша слоту 21 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 22 key"
-msgstr ""
+msgstr "Клавіша слоту 22 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 23 key"
-msgstr ""
+msgstr "Клавіша слоту 23 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 24 key"
-msgstr ""
+msgstr "Клавіша слоту 24 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 25 key"
-msgstr ""
+msgstr "Клавіша слоту 25 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 26 key"
-msgstr ""
+msgstr "Клавіша слоту 26 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 27 key"
-msgstr ""
+msgstr "Клавіша слоту 27 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 28 key"
-msgstr ""
+msgstr "Клавіша слоту 28 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 29 key"
-msgstr ""
+msgstr "Клавіша слоту 29 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 3 key"
-msgstr ""
+msgstr "Клавіша слоту 3 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 30 key"
-msgstr ""
+msgstr "Клавіша слоту 30 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 31 key"
-msgstr ""
+msgstr "Клавіша слоту 31 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 32 key"
-msgstr ""
+msgstr "Клавіша слоту 32 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 4 key"
-msgstr ""
+msgstr "Клавіша слоту 4 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 5 key"
-msgstr ""
+msgstr "Клавіша слоту 5 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 6 key"
-msgstr ""
+msgstr "Клавіша слоту 6 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 7 key"
-msgstr ""
+msgstr "Клавіша слоту 7 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 8 key"
-msgstr ""
+msgstr "Клавіша слоту 8 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "Hotbar slot 9 key"
-msgstr ""
+msgstr "Клавіша слоту 9 швидкої панелі"
 
 #: src/settings_translation_file.cpp
 msgid "How deep to make rivers."
-msgstr ""
+msgstr "Як глибоко робити ріки."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3790,7 +3864,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "How wide to make rivers."
-msgstr ""
+msgstr "Як широко робити ріки."
 
 #: src/settings_translation_file.cpp
 msgid "Humidity blend noise"
@@ -3907,7 +3981,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Ignore world errors"
-msgstr ""
+msgstr "Ігнорувати помилки світу"
 
 #: src/settings_translation_file.cpp
 msgid "In-Game"
@@ -3927,7 +4001,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Inc. volume key"
-msgstr "Ð\97бÑ\96лÑ\8cÑ\88иÑ\82и Ð³Ñ\83Ñ\87нÑ\96Ñ\81Ñ\82Ñ\8c"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ð·Ð±Ñ\96лÑ\8cÑ\88. Ð³Ñ\83Ñ\87ноÑ\81Ñ\82Ñ\96"
 
 #: src/settings_translation_file.cpp
 msgid "Initial vertical speed when jumping, in nodes per second."
@@ -3940,7 +4014,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3977,28 +4051,27 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Inventory items animations"
-msgstr ""
+msgstr "Анімація предметів інвентаря"
 
 #: src/settings_translation_file.cpp
 msgid "Inventory key"
-msgstr "Ð\86нвенÑ\82аÑ\80"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ñ\96нвенÑ\82аÑ\80Ñ\8f"
 
 #: src/settings_translation_file.cpp
 msgid "Invert mouse"
-msgstr ""
+msgstr "Інвертувати мишку"
 
 #: src/settings_translation_file.cpp
 msgid "Invert vertical mouse movement."
-msgstr ""
+msgstr "Інвертувати вертикальні рухи мишки."
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Italic font path"
-msgstr "Шлях до шрифту"
+msgstr "Шлях до похилого шрифту"
 
 #: src/settings_translation_file.cpp
 msgid "Italic monospace font path"
-msgstr ""
+msgstr "Шлях до похилого моноширного шрифту"
 
 #: src/settings_translation_file.cpp
 msgid "Item entity TTL"
@@ -4006,7 +4079,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Iterations"
-msgstr ""
+msgstr "Ітерації"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4018,14 +4091,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Joystick ID"
-msgstr ""
+msgstr "ІД джойстика"
 
 #: src/settings_translation_file.cpp
 msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4034,7 +4107,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Joystick type"
-msgstr ""
+msgstr "Тип джойстика"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4087,11 +4160,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Jump key"
-msgstr "Стрибок"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ð¡Ñ\82Ñ\80ибок"
 
 #: src/settings_translation_file.cpp
 msgid "Jumping speed"
-msgstr ""
+msgstr "Швидкість стрибання"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4099,6 +4172,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для зменшення видимості.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4106,6 +4182,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для зменшення гучності.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4113,6 +4192,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для копання.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4120,6 +4202,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для кидання поточного предмета.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4127,6 +4212,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для збільшення видимості.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4134,6 +4222,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для збільшення гучності.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4141,6 +4232,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для стрибання.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4148,6 +4242,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для швидкого руху у швидкому режимі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4163,6 +4260,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для руху гравця вперед.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4170,6 +4270,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для руху гравця вліво.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4177,6 +4280,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для руху гравця вправо.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4184,6 +4290,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для приглушення гри.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4191,6 +4300,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для відкривання вікна чату для введення команд.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4198,6 +4310,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для відкривання вікна чату для набирання локальних команд.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4205,6 +4320,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для відкривання вікна чату.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4212,6 +4330,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для відкривання інвентаря.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4219,6 +4340,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша покласти.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4226,6 +4350,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 11-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4233,6 +4360,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 12-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4240,6 +4370,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 13-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4247,6 +4380,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 14-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4254,6 +4390,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 15-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4261,6 +4400,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 16-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4268,6 +4410,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 17-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4275,6 +4420,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 18-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4282,6 +4430,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 19-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4289,6 +4440,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша для вибору 20-го слоту швидкої панелі.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4564,6 +4718,9 @@ msgid ""
 "See http://irrlicht.sourceforge.net/docu/namespaceirr."
 "html#a54da2a0e231901735e3da1b0edf72eb3"
 msgstr ""
+"Клавіша ввімкнення відображення HUD.\n"
+"Дивіться http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4775,7 +4932,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Main menu script"
-msgstr ""
+msgstr "Скрипт основного меню"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4796,7 +4953,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Map directory"
-msgstr "Тека мапи"
+msgstr "Ð\9aаÑ\82алог мапи"
 
 #: src/settings_translation_file.cpp
 msgid "Map generation attributes specific to Mapgen Carpathian."
@@ -4854,7 +5011,7 @@ msgid "Map save interval"
 msgstr "Інтервал збереження мапи"
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4894,9 +5051,8 @@ msgid "Mapgen Fractal"
 msgstr "Генератор світу: фрактальний"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen Fractal specific flags"
-msgstr "Ð\93енеÑ\80аÑ\82оÑ\80 Ñ\81вÑ\96Ñ\82Ñ\83: Ñ\84Ñ\80акÑ\82алÑ\8cний"
+msgstr "Ð\9cÑ\96Ñ\82ки Ð´Ð»Ñ\8f Ñ\84Ñ\80акÑ\82алÑ\8cного Ò\91енеÑ\80аÑ\82оÑ\80а Ñ\81вÑ\96Ñ\82Ñ\83"
 
 #: src/settings_translation_file.cpp
 msgid "Mapgen V5"
@@ -4931,14 +5087,12 @@ msgid "Mapgen Valleys specific flags"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen debug"
-msgstr "Налагодження генерації світу"
+msgstr "Налагодження ґенератора світу"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Mapgen name"
-msgstr "Назва генерації світу"
+msgstr "Назва ґенератора світу"
 
 #: src/settings_translation_file.cpp
 msgid "Max block generate distance"
@@ -4949,28 +5103,24 @@ msgid "Max block send distance"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Max liquids processed per step."
-msgstr "Ð\9cакÑ\81ималÑ\8cна ÐºÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c Ñ\80Ñ\96дин, Ð¾Ð±Ñ\80облениÑ\85 на крок."
+msgstr "Ð\9dайбÑ\96лÑ\8cÑ\88а ÐºÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c Ñ\80Ñ\96дини на крок."
 
 #: src/settings_translation_file.cpp
 msgid "Max. clearobjects extra blocks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Max. packets per iteration"
-msgstr "Ð\9cакÑ\81ималÑ\8cна ÐºÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c Ð¿Ð°ÐºÐµÑ\82Ñ\96в Ð·Ð° Ð¾Ð´Ð½Ñ\83 ітерацію"
+msgstr "Ð\9dайбÑ\96лÑ\8cÑ\88а ÐºÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c Ð¿Ð°ÐºÐµÑ\82Ñ\96в Ð½Ð° ітерацію"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum FPS"
-msgstr "Ð\9cакÑ\81ималÑ\8cна ÐºÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c ÐºÐ°Ð´Ñ\80Ñ\96в Ð² Ñ\81екÑ\83ндÑ\83 (FPS)"
+msgstr "Ð\9dайбÑ\96лÑ\8cÑ\88а ÐºÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c FPS"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Maximum FPS when the window is not focused, or when the game is paused."
-msgstr "Ð\9cакÑ\81имÑ\83м FPS Ð¿Ñ\80и Ð¿Ð°Ñ\83зÑ\96."
+msgstr "Ð\9dайбÑ\96лÑ\8cÑ\88а ÐºÑ\96лÑ\8cкÑ\96Ñ\81Ñ\82Ñ\8c FPS, ÐºÐ¾Ð»Ð¸ Ð²Ñ\96кно Ð¿Ð¾Ð·Ð° Ñ\84окÑ\83Ñ\81ом Ð°Ð±Ð¾ Ð³Ñ\80Ñ\83 Ð¿Ñ\80изÑ\83пинено."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
@@ -5059,7 +5209,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum objects per block"
-msgstr ""
+msgstr "Найбільша кількість обʼєктів на блок"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5095,7 +5245,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
-msgstr "Ð\9cакÑ\81имÑ\83м користувачів"
+msgstr "Ð\9dайбÑ\96лÑ\8cÑ\88е користувачів"
 
 #: src/settings_translation_file.cpp
 msgid "Menus"
@@ -5107,7 +5257,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Message of the day"
-msgstr ""
+msgstr "Повідомлення дня"
 
 #: src/settings_translation_file.cpp
 msgid "Message of the day displayed to players connecting."
@@ -5127,7 +5277,7 @@ msgstr "Мінімапа"
 
 #: src/settings_translation_file.cpp
 msgid "Minimap key"
-msgstr ""
+msgstr "Клавіша мінімапи"
 
 #: src/settings_translation_file.cpp
 msgid "Minimap scan height"
@@ -5154,15 +5304,19 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
-msgstr ""
+msgid "Modifies the size of the HUD elements."
+msgstr "Змінює розмір елементів HUD."
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font path"
-msgstr ""
+msgstr "Шлях до моноширного шрифту"
 
 #: src/settings_translation_file.cpp
 msgid "Monospace font size"
+msgstr "Розмір моноширного шрифту"
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5205,7 +5359,7 @@ msgstr "Вимкнути звук"
 
 #: src/settings_translation_file.cpp
 msgid "Mute sound"
-msgstr ""
+msgstr "Заглушити звук"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5263,7 +5417,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Noises"
-msgstr ""
+msgstr "Шуми"
 
 #: src/settings_translation_file.cpp
 msgid "Number of emerge threads"
@@ -5286,13 +5440,13 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Online Content Repository"
-msgstr ""
+msgstr "Репозиторій мережевого вмісту"
 
 #: src/settings_translation_file.cpp
 msgid "Opaque liquids"
@@ -5310,11 +5464,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5337,17 +5493,13 @@ msgstr "Шлях до теки з текстурами. Всі текстури
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5368,18 +5520,16 @@ msgid "Physics"
 msgstr "Фізика"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Pitch move key"
-msgstr "Ð\9aнопка Ð¿Ð¾Ð»Ñ\8cоÑ\82Ñ\83"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ð·Ð¼Ñ\96ни Ð²Ð¸Ñ\81оÑ\82и"
 
 #: src/settings_translation_file.cpp
 msgid "Pitch move mode"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Place key"
-msgstr "Ð\9aнопка Ð´Ð»Ñ\8f Ð¿Ð¾Ð»Ñ\8cоÑ\82Ñ\83"
+msgstr "Ð\9aлавÑ\96Ñ\88а Ð¿Ð¾ÐºÐ»Ð°Ñ\81Ñ\82и"
 
 #: src/settings_translation_file.cpp
 msgid "Place repetition interval"
@@ -5393,7 +5543,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Player name"
-msgstr "Ім'я гравця"
+msgstr "Імʼя гравця"
 
 #: src/settings_translation_file.cpp
 msgid "Player transfer distance"
@@ -5404,9 +5554,8 @@ msgid "Player versus player"
 msgstr "Гравець проти гравця"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Poisson filtering"
-msgstr "Ð\91Ñ\96лÑ\96нÑ\96йна Ñ\84Ñ\96лÑ\8cÑ\82Ñ\80аÑ\86Ñ\96Ñ\8f"
+msgstr "ФÑ\96лÑ\8cÑ\82Ñ\80Ñ\83ваннÑ\8f Ð\9fÑ\83аÑ\81она"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5453,9 +5602,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5483,20 +5632,19 @@ msgstr "Вибір діапазону"
 
 #: src/settings_translation_file.cpp
 msgid "Recent Chat Messages"
-msgstr ""
+msgstr "Останні повідомлення чату"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Regular font path"
-msgstr "ШлÑ\8fÑ\85 Ð´Ð»Ñ\8f Ð·Ð²Ñ\96ту"
+msgstr "ШлÑ\8fÑ\85 Ð´Ð¾ Ð·Ð²Ð¸Ñ\87айного Ñ\88Ñ\80иÑ\84ту"
 
 #: src/settings_translation_file.cpp
 msgid "Remote media"
-msgstr ""
+msgstr "Віддалені ресурси"
 
 #: src/settings_translation_file.cpp
 msgid "Remote port"
-msgstr ""
+msgstr "Віддалений порт"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5547,9 +5695,8 @@ msgid "Right key"
 msgstr "Права клавіша"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "River channel depth"
-msgstr "Ð\93либина Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ\85 Ð¿ÐµÑ\87еÑ\80"
+msgstr "Ð\93либина ÐºÐ°Ð½Ð°Ð»Ñ\83 Ñ\80Ñ\96Ñ\87ки"
 
 #: src/settings_translation_file.cpp
 msgid "River channel width"
@@ -5557,7 +5704,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "River depth"
-msgstr ""
+msgstr "Глибина річки"
 
 #: src/settings_translation_file.cpp
 msgid "River noise"
@@ -5565,7 +5712,7 @@ msgstr "Річковий шум"
 
 #: src/settings_translation_file.cpp
 msgid "River size"
-msgstr ""
+msgstr "Розмір річки"
 
 #: src/settings_translation_file.cpp
 msgid "River valley width"
@@ -5626,7 +5773,7 @@ msgstr "Ширина екрана"
 
 #: src/settings_translation_file.cpp
 msgid "Screenshot folder"
-msgstr ""
+msgstr "Тека для знімків екрана"
 
 #: src/settings_translation_file.cpp
 msgid "Screenshot format"
@@ -5700,7 +5847,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Server / Singleplayer"
-msgstr "СеÑ\80веÑ\80 / Ð\93ра"
+msgstr "СеÑ\80веÑ\80 / Ð\9eдиноÑ\87на Ð³ра"
 
 #: src/settings_translation_file.cpp
 msgid "Server URL"
@@ -5728,11 +5875,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Serverlist URL"
-msgstr "Адреса списку публічних серверів"
+msgstr "Адреса списку серверів"
 
 #: src/settings_translation_file.cpp
 msgid "Serverlist file"
-msgstr "Файл списку публічних серверів"
+msgstr "Файл списку серверів"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5752,26 +5899,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5818,9 +5957,8 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Shadow filter quality"
-msgstr "Якість знімку"
+msgstr "Якість фільтру тіні"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
@@ -5850,28 +5988,27 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Show debug info"
-msgstr ""
+msgstr "Показати дані зневадження"
 
 #: src/settings_translation_file.cpp
 msgid "Show entity selection boxes"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Show entity selection boxes\n"
 "A restart is required after changing this."
 msgstr ""
-"Ð\92казаÑ\82и Ð¼Ð¾Ð²Ñ\83. Ð\97алиÑ\88Ñ\82е Ð¿Ð¾Ñ\80ожнÑ\96м, Ñ\89об Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82овÑ\83ваÑ\82и Ñ\81иÑ\81Ñ\82емнÑ\83 Ð¼Ð¾Ð²Ñ\83.\n"
-"Потрібен перезапуск після цієї зміни."
+"Ð\9fоказаÑ\82и Ð¿Ð¾Ð»Ðµ Ð²Ð¸Ð´Ñ\96леннÑ\8f Ð¾Ð±Ê¼Ñ\94кÑ\82Ñ\96в\n"
+"Після зміни потрібно перезапустити."
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Shutdown message"
-msgstr ""
+msgstr "Вимкнути повідомлення"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5949,9 +6086,8 @@ msgid "Sneaking speed, in nodes per second."
 msgstr ""
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Soft shadow radius"
-msgstr "Радіус хмар"
+msgstr "Радіус легких тіней"
 
 #: src/settings_translation_file.cpp
 msgid "Sound"
@@ -5972,6 +6108,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6082,7 +6226,7 @@ msgstr "Шлях до текстури"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6100,8 +6244,8 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
-msgstr ""
+msgid "The dead zone of the joystick"
+msgstr "Мертва зона джойстика"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6169,7 +6313,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6207,7 +6351,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "The type of joystick"
-msgstr ""
+msgstr "Тип джойстика"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6232,11 +6376,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Time send interval"
-msgstr ""
+msgstr "Період надсилання часу"
 
 #: src/settings_translation_file.cpp
 msgid "Time speed"
-msgstr ""
+msgstr "Швидкість часу"
 
 #: src/settings_translation_file.cpp
 msgid "Timeout for client to remove unused map data from memory."
@@ -6263,9 +6407,13 @@ msgid "Touch screen threshold"
 msgstr "Межа чутливості дотику"
 
 #: src/settings_translation_file.cpp
-msgid "Trees noise"
+msgid "Tradeoffs for performance"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Trees noise"
+msgstr "Шум дерев"
+
 #: src/settings_translation_file.cpp
 msgid "Trilinear filtering"
 msgstr "Трилінійна фільтрація"
@@ -6332,7 +6480,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6450,13 +6598,15 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Volume"
-msgstr "Гучність звуку"
+msgstr "Гучність"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Volume of all sounds.\n"
 "Requires the sound system to be enabled."
 msgstr ""
+"Гучність усіх звуків.\n"
+"Вимагає увімкнення системи звуку."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6469,11 +6619,11 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Walking and flying speed, in nodes per second."
-msgstr ""
+msgstr "Швидкість ходьби і польоту, в блоках за секунду."
 
 #: src/settings_translation_file.cpp
 msgid "Walking speed"
-msgstr ""
+msgstr "Швидкість ходьби"
 
 #: src/settings_translation_file.cpp
 msgid "Walking, flying and climbing speed in fast mode, in nodes per second."
@@ -6481,7 +6631,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Water level"
-msgstr ""
+msgstr "Рівень води"
 
 #: src/settings_translation_file.cpp
 msgid "Water surface level of the world."
@@ -6489,35 +6639,35 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Waving Nodes"
-msgstr "Ð\91локи, Ñ\89о ÐºÐ¾Ð»Ð¸Ð²Ð°Ñ\8eÑ\82Ñ\8cÑ\81Ñ\8f"
+msgstr "Ð\9aоливаннÑ\8f Ð±Ð»Ð¾ÐºÑ\96в"
 
 #: src/settings_translation_file.cpp
 msgid "Waving leaves"
-msgstr "Ð\9bиÑ\81Ñ\82Ñ\8f, Ñ\89о ÐºÐ¾Ð»Ð¸Ð²Ð°Ñ\94Ñ\82Ñ\8cÑ\81я"
+msgstr "Ð\9aоливаннÑ\8f Ð»Ð¸Ñ\81Ñ\82я"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids"
-msgstr "Хвилясті Рідини"
+msgstr "Хвилясті рідини"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids wave height"
-msgstr "Ð\9aоливаÑ\82и Ð²Ð¾Ð´Ñ\83"
+msgstr "Ð\92иÑ\81оÑ\82а Ñ\85вилÑ\96 Ñ\85вилÑ\8fÑ\81Ñ\82иÑ\85 Ñ\80Ñ\96дин"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids wave speed"
-msgstr "Ð\9aоливаÑ\82и Ð»Ð¸Ñ\81Ñ\82Ñ\8f"
+msgstr "ШвидкÑ\96Ñ\81Ñ\82Ñ\8c Ñ\85вилÑ\96 Ñ\85вилÑ\8fÑ\81Ñ\82иÑ\85 Ñ\80Ñ\96дин"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Waving liquids wavelength"
-msgstr "Ð\9aоливаÑ\82и Ð²Ð¾Ð´Ñ\83"
+msgstr "Ð\94овжина Ñ\85вилÑ\96 Ñ\85вилÑ\8fÑ\81Ñ\82иÑ\85 Ñ\80Ñ\96дин"
 
 #: src/settings_translation_file.cpp
 msgid "Waving plants"
-msgstr ""
+msgstr "Коливання рослин"
+
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr "Колір вебпосилання"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6540,7 +6690,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6548,14 +6698,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6681,24 +6824,6 @@ msgstr "Y-Рівень нижнього рельєфу та морського 
 msgid "Y-level of seabed."
 msgstr "Y-Рівень морського дна."
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr ""
@@ -6711,6 +6836,12 @@ msgstr ""
 msgid "cURL parallel limit"
 msgstr ""
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Творчість: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Ушкодження: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -6766,6 +6897,9 @@ msgstr ""
 #~ msgid "IPv6 support."
 #~ msgstr "Підтримка IPv6."
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "Встановлення: файл: \"$1\""
+
 #~ msgid "Lava depth"
 #~ msgstr "Глибина лави"
 
@@ -6826,6 +6960,9 @@ msgstr ""
 #~ msgid "Start Singleplayer"
 #~ msgstr "Почати одиночну гру"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "Для того, щоб увімкнути шейдери, потрібно мати драйвер OpenGL."
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "Кінематографічний режим"
 
@@ -6835,5 +6972,9 @@ msgstr ""
 #~ msgid "Yes"
 #~ msgstr "Так"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Ви загинули"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "no"
index 60be1b23937650c917a03ab9c9b472e5f1b506bc..4f6f41eb051804d406a294492d02f746eec87f7e 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vietnamese (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2020-06-13 21:08+0000\n"
-"Last-Translator: darkcloudcat <leducthn@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-04 06:53+0000\n"
+"Last-Translator: IAmOlive <nhathungtran2011@gmail.com>\n"
 "Language-Team: Vietnamese <https://hosted.weblate.org/projects/minetest/"
 "minetest/vi/>\n"
 "Language: vi\n"
@@ -12,44 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.1-dev\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "Xóa hàng đợi trò chuyện"
 
 #: builtin/client/chatcommands.lua
 msgid "Empty command."
-msgstr ""
+msgstr "Lệnh trống."
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "Trình đơn chính"
+msgstr "Thoát ra màn hình chính"
 
 #: builtin/client/chatcommands.lua
 msgid "Invalid command: "
-msgstr ""
+msgstr "Lệnh không hợp lệ: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "Lệnh đã dùng: "
 
 #: builtin/client/chatcommands.lua
 msgid "List online players"
-msgstr ""
+msgstr "Liệt kê những người đang chơi trực tuyến"
 
 #: builtin/client/chatcommands.lua
 msgid "Online players: "
-msgstr ""
+msgstr "Những người đang chơi trực tuyến: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "Hàng đợi trò chuyện đã trống."
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "Lệnh này đã bị cấm trong máy chủ này."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -57,53 +56,54 @@ msgstr "Hồi sinh"
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "You died"
-msgstr "Bạn đã chết"
-
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "Bạn đã chết"
+msgstr "Bạn đã bị chết"
 
 #: builtin/common/chatcommands.lua
 msgid "Available commands:"
-msgstr ""
+msgstr "Lệnh có sẵn:"
 
 #: builtin/common/chatcommands.lua
 msgid "Available commands: "
-msgstr ""
+msgstr "Lệnh có sẵn: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "Lệnh không có sẵn: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "Trợ giúp về lệnh"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"Dùng '.help <câu lệnh>' để có thêm thông tin về một câu lệnh hoặc dùng '."
+"help all' để xem danh sách về những câu lệnh có sẵn."
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <câu lệnh>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
-msgstr ""
+msgstr "OK"
+
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<không có sẵn>"
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
-msgstr "Đã xảy ra lỗi trong tập lệnh Lua:"
+msgstr "Một lỗi đã xảy ra trong tập lệnh Lua:"
 
 #: builtin/fstk/ui.lua
 msgid "An error occurred:"
-msgstr "Xảy ra lỗi:"
+msgstr "Đã xảy ra lỗi:"
 
 #: builtin/fstk/ui.lua
 msgid "Main menu"
-msgstr "Trình đơn chính"
+msgstr "Màn hình chính"
 
 #: builtin/fstk/ui.lua
 msgid "Reconnect"
@@ -115,7 +115,7 @@ msgstr "Máy chủ đã yêu cầu kết nối lại:"
 
 #: builtin/mainmenu/common.lua
 msgid "Protocol version mismatch. "
-msgstr "Phiên bản giao thức không khớp "
+msgstr "Phiên bản giao thức không khớp. "
 
 #: builtin/mainmenu/common.lua
 msgid "Server enforces protocol version $1. "
@@ -155,11 +155,11 @@ msgstr "Vô hiệu hóa tất cả"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Disable modpack"
-msgstr "Vô hiệu hóa modpack"
+msgstr "Vô hiệu hóa gói mod"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Enable all"
-msgstr "Cho phép tất cả"
+msgstr "Kích hoạt tất cả"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Enable modpack"
@@ -170,43 +170,40 @@ msgid ""
 "Failed to enable mod \"$1\" as it contains disallowed characters. Only "
 "characters [a-z0-9_] are allowed."
 msgstr ""
-"Không thể bật mod \"$ 1\" vì nó chứa các ký tự không được phép. Chỉ cho phép "
-"các ký tự [a-z0-9_]."
+"Không thể bật mod \"$1\" vì nó chứa các ký tự không được phép. Chỉ cho phép "
+"các ký tự Latinh; chữ số và ký tự \"_\"."
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Find More Mods"
-msgstr ""
+msgstr "Tìm thêm mod"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "Mod:"
 msgstr "Mod:"
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No (optional) dependencies"
-msgstr "Phụ thuộc tùy chọn:"
+msgstr "Không có phần phụ thuộc bắt buộc nào"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No game description provided."
 msgstr "Không có mô tả trò chơi được cung cấp."
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No hard dependencies"
-msgstr "Phụ thuộc tùy chọn:"
+msgstr "Không có phần phụ thuộc khó nào"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "No modpack description provided."
-msgstr "Không có mô tả modpack được cung cấp."
+msgstr "Không có mô tả mod được cung cấp."
 
 #: builtin/mainmenu/dlg_config_world.lua
-#, fuzzy
 msgid "No optional dependencies"
-msgstr "Phụ thuộc tùy chọn:"
+msgstr "Không có phần phụ thuộc tùy chọn nào"
 
 #: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua
 msgid "Optional dependencies:"
-msgstr "Phụ thuộc tùy chọn:"
+msgstr "Phần phụ thuá»\99c tùy chá»\8dn:"
 
 #: builtin/mainmenu/dlg_config_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp
@@ -215,19 +212,19 @@ msgstr "Tiết kiệm"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "World:"
-msgstr "Thế giới"
+msgstr "Thế giới:"
 
 #: builtin/mainmenu/dlg_config_world.lua
 msgid "enabled"
-msgstr "kích hoạt"
+msgstr "đã kích hoạt"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "\"$1\" already exists. Would you like to overwrite it?"
-msgstr ""
+msgstr "Đã có \"$1\". Bạn có muốn ghi đè nó không?"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 and $2 dependencies will be installed."
-msgstr ""
+msgstr "Phần phụ thuộc $1 và $2 sẽ được cài đặt."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
@@ -238,19 +235,20 @@ msgid ""
 "$1 downloading,\n"
 "$2 queued"
 msgstr ""
+"$1 đang cài đặt,\n"
+"$2 đã được xếp vào hàng đợi"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "$1 downloading..."
-msgstr "Đang tải..."
+msgstr "Đang tải xuống $1..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr ""
+msgstr "Không thể tìm thấy phần phụ thuộc $1 (cần thiết)."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
-msgstr ""
+msgstr "$1 sẽ được cài, phần phụ thuộc $2 sẽ được bỏ qua."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "All packages"
@@ -258,28 +256,27 @@ msgstr "Tất cả các gói"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Already installed"
-msgstr ""
+msgstr "Đã được cài"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Back to Main Menu"
-msgstr ""
+msgstr "Trở về màn hình chính"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Base Game:"
-msgstr ""
+msgstr "Trò chơi cơ bản:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "ContentDB is not available when Minetest was compiled without cURL"
-msgstr ""
+msgstr "ContentDB không có sẵn khi Minetest được cài mà không có cURL"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Downloading..."
-msgstr "Đang tải..."
+msgstr "Đang tải xuống..."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Failed to download $1"
-msgstr ""
+msgstr "Không tải xuống được $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -288,16 +285,19 @@ msgstr "Trò chơi"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Install"
-msgstr ""
+msgstr "Cài đặt"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Install $1"
-msgstr ""
+msgstr "Cài đặt $1"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Install missing dependencies"
-msgstr "Phụ thuộc tùy chọn:"
+msgstr "Cài phần phụ thuộc bị thiếu"
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "Cài đặt: Loại tệp không được hỗ trợ hoặc tệp lưu trữ bị hỏng"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -306,143 +306,144 @@ msgstr "Mod"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No packages could be retrieved"
-msgstr ""
+msgstr "Không nhận được gói nào"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No results"
-msgstr ""
+msgstr "Không có kết quả"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "No updates"
-msgstr ""
+msgstr "Không có cập nhật mới"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Not found"
-msgstr ""
+msgstr "Không tìm thấy"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Overwrite"
-msgstr ""
+msgstr "Ghi đè"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Please check that the base game is correct."
-msgstr ""
+msgstr "Vui lòng kiểm tra xem trò chơi này có đúng không."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Queued"
-msgstr ""
+msgstr "Đã xếp vào hàng đợi"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Texture packs"
-msgstr ""
+msgstr "Gói cấu hình khối"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Uninstall"
-msgstr ""
+msgstr "Gỡ cài đặt"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update"
-msgstr ""
+msgstr "Cập nhật"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Update All [$1]"
-msgstr ""
+msgstr "Cập nhật tất cả [$1]"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "View more information in a web browser"
-msgstr ""
+msgstr "Xem thêm thông tin trên trình duyệt web của bạn"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "A world named \"$1\" already exists"
-msgstr ""
+msgstr "Thế giới \"$1\" đã tồn tại"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Additional terrain"
-msgstr ""
+msgstr "Địa hình bổ sung"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Altitude chill"
-msgstr ""
+msgstr "Độ cao lạnh"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Altitude dry"
-msgstr ""
+msgstr "Độ cao khô ráo"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Biome blending"
-msgstr ""
+msgstr "Các khu vực sinh học đang trộn lại với nhau"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Biomes"
-msgstr ""
+msgstr "Khu sinh học"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Caverns"
-msgstr ""
+msgstr "Hang động"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Caves"
-msgstr ""
+msgstr "Hang động"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Create"
-msgstr ""
+msgstr "Tạo"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Decorations"
-msgstr ""
+msgstr "Vật trang trí"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download a game, such as Minetest Game, from minetest.net"
 msgstr ""
+"Tải xuống một trò chơi, chẳng hạn như trò chơi Minetest, từ minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Download one from minetest.net"
-msgstr ""
+msgstr "Tải xuống một trò chơi từ minetest.net"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Dungeons"
-msgstr ""
+msgstr "Ngục tối"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Flat terrain"
-msgstr ""
+msgstr "Địa hình phẳng"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floating landmasses in the sky"
-msgstr ""
+msgstr "Vùng đất lơ lửng trên trời"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Floatlands (experimental)"
-msgstr ""
+msgstr "Vùng đất lơ lửng (đang trong thử nghiệm)"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Game"
-msgstr ""
+msgstr "Trò chơi"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Generate non-fractal terrain: Oceans and underground"
-msgstr ""
+msgstr "Tạo địa hình không phân dạng: Đại dương và lòng đất"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Hills"
-msgstr ""
+msgstr "Đồi"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Humid rivers"
-msgstr ""
+msgstr "Sông ẩm ướt"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Increases humidity around rivers"
-msgstr ""
+msgstr "Tăng độ ẩm xung quanh sông"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Lakes"
-msgstr ""
+msgstr "Hồ nước"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Low humidity and high heat causes shallow or dry rivers"
-msgstr ""
+msgstr "Độ ẩm thấp và nhiệt độ cao làm cho sông cạn hoặc khô"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen"
@@ -450,43 +451,43 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen flags"
-msgstr ""
+msgstr "Cờ của Mapgen"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mapgen-specific flags"
-msgstr ""
+msgstr "Cờ cụ thể của Mapgen"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mountains"
-msgstr ""
+msgstr "Núi"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Mud flow"
-msgstr ""
+msgstr "Suối bùn"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Network of tunnels and caves"
-msgstr ""
+msgstr "Mạng lưới đường hầm và hang động"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "No game selected"
-msgstr ""
+msgstr "Không có trò chơi nào được chọn"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces heat with altitude"
-msgstr ""
+msgstr "Giảm nhiệt theo độ cao"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces humidity with altitude"
-msgstr ""
+msgstr "Giảm độ ẩm theo độ cao"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Rivers"
-msgstr ""
+msgstr "Sông"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Sea level rivers"
-msgstr ""
+msgstr "Sông theo mực nước biển"
 
 #: builtin/mainmenu/dlg_create_world.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -495,109 +496,113 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Smooth transition between biomes"
-msgstr ""
+msgstr "Chuyển đổi suôn sẻ giữa các khu sinh học"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid ""
 "Structures appearing on the terrain (no effect on trees and jungle grass "
 "created by v6)"
 msgstr ""
+"Các cấu trúc xuất hiện trên địa hình (không ảnh hưởng đến cây cối, cỏ rừng "
+"và được tạo bởi v6)"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Structures appearing on the terrain, typically trees and plants"
-msgstr ""
+msgstr "Các cấu trúc xuất hiện trên địa hình, điển hình là cây cối và thực vật"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert"
-msgstr ""
+msgstr "Ôn đới, sa mạc"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle"
-msgstr ""
+msgstr "Ôn đới, sa mạc, rừng rậm"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr ""
+msgstr "Ôn đới, sa mạc, rừng rậm, đồng cỏ, rừng taiga"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Terrain surface erosion"
-msgstr ""
+msgstr "Xói mòn bề mặt địa hình"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
-msgstr ""
+msgstr "Cây và cỏ rừng"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Vary river depth"
-msgstr ""
+msgstr "Độ sâu sông thay đổi"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Very large caverns deep in the underground"
-msgstr ""
+msgstr "Các hang động lớn nằm sâu trong lòng đất"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Warning: The Development Test is meant for developers."
-msgstr ""
+msgstr "Cảnh báo: Kiểm tra Phát triển chỉ dành cho các nhà phát triển."
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "World name"
-msgstr ""
+msgstr "Tên thế giới"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "You have no games installed."
-msgstr ""
+msgstr "Bạn chưa cài đặt trò chơi nào."
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "Are you sure you want to delete \"$1\"?"
-msgstr ""
+msgstr "Bạn có chắc chắn muốn xóa \"$1\" không?"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 #: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua
 #: src/client/keycode.cpp
 msgid "Delete"
-msgstr ""
+msgstr "Xóa"
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: failed to delete \"$1\""
-msgstr ""
+msgstr "pkgmgr: không xóa được \"$1\""
 
 #: builtin/mainmenu/dlg_delete_content.lua
 msgid "pkgmgr: invalid path \"$1\""
-msgstr ""
+msgstr "pkgmgr: đường dẫn \"$1\" không hợp lệ"
 
 #: builtin/mainmenu/dlg_delete_world.lua
 msgid "Delete World \"$1\"?"
-msgstr ""
+msgstr "Xóa thế giới \"$ 1\"?"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid "Accept"
-msgstr ""
+msgstr "Chấp nhận"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid "Rename Modpack:"
-msgstr ""
+msgstr "Đổi tên mod:"
 
 #: builtin/mainmenu/dlg_rename_modpack.lua
 msgid ""
 "This modpack has an explicit name given in its modpack.conf which will "
 "override any renaming here."
 msgstr ""
+"Mod này có một tên rõ ràng được đưa ra trong tệp modpack.conf của nó, tên "
+"này sẽ ghi đè bất kỳ sự đổi tên nào ở đây."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "(No description of setting given)"
-msgstr ""
+msgstr "(Không có mô tả về Cài đặt nào được đưa ra)"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "2D Noise"
-msgstr ""
+msgstr "Âm thanh 2D"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "< Back to Settings page"
-msgstr ""
+msgstr "< Về trang Cài đặt"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Browse"
-msgstr ""
+msgstr "Duyệt"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua
 msgid "Disabled"
@@ -605,7 +610,7 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Edit"
-msgstr ""
+msgstr "Chỉnh sửa"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Enabled"
@@ -613,59 +618,59 @@ msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Lacunarity"
-msgstr ""
+msgstr "Khoảng cách"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Octaves"
-msgstr ""
+msgstr "Quãng tám"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Offset"
 msgstr ""
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
-msgstr ""
+msgid "Persistence"
+msgstr "Sự bền bỉ"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid integer."
-msgstr ""
+msgstr "Vui lòng nhập một số nguyên hợp lệ."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid number."
-msgstr ""
+msgstr "Vui lòng nhập một số hợp lệ."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Restore Default"
-msgstr ""
+msgstr "Phục hồi Cài đặt mặc định"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
 msgid "Scale"
-msgstr ""
+msgstr "Tỉ lệ"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua
 msgid "Search"
-msgstr ""
+msgstr "Tìm kiếm"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Select directory"
-msgstr ""
+msgstr "Chọn thư mục"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Select file"
-msgstr ""
+msgstr "Chọn tệp"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Show technical names"
-msgstr ""
+msgstr "Hiển thị tên kỹ thuật"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "The value must be at least $1."
-msgstr ""
+msgstr "Giá trị ít nhất phải là $1."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "The value must not be larger than $1."
-msgstr ""
+msgstr "Giá trị không được lớn hơn $1."
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "X"
@@ -697,14 +702,14 @@ msgstr ""
 #. main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "absvalue"
-msgstr ""
+msgstr "Giá trị tuyệt đối"
 
 #. ~ "defaults" is a noise parameter flag.
 #. It describes the default processing options
 #. for noise settings in main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "defaults"
-msgstr ""
+msgstr "Mặc định"
 
 #. ~ "eased" is a noise parameter flag.
 #. It is used to make the map smoother and
@@ -712,11 +717,11 @@ msgstr ""
 #. main menu -> "All Settings".
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "eased"
-msgstr ""
+msgstr "Nới lỏng"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "$1 (Enabled)"
-msgstr ""
+msgstr "$1 (đã bật)"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "$1 mods"
@@ -724,43 +729,35 @@ msgstr ""
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Failed to install $1 to $2"
-msgstr ""
+msgstr "Không cài đặt được $1 đến $2"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Install Mod: Unable to find real mod name for: $1"
-msgstr ""
+msgstr "Cài đặt mod: Không thể tìm thấy tên mod thật cho: $1"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr ""
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr ""
+msgstr "Cài đặt mod: Không thể tìm thấy tên thư mục phù hợp cho gói mod $1"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
-msgstr ""
+msgstr "Không tìm thấy một mod hoặc gói mod hợp lệ"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to install a $1 as a texture pack"
-msgstr ""
+msgstr "Không thể cài đặt $1 dưới dạng gói kết cấu địa hình"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to install a game as a $1"
-msgstr ""
+msgstr "Không thể cài đặt trò chơi dưới dạng $1"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to install a mod as a $1"
-msgstr ""
+msgstr "Không thể cài đặt mod dưới dạng $1"
 
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to install a modpack as a $1"
-msgstr ""
+msgstr "Không thể cài đặt gói mod dưới dạng $1"
 
 #: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp
 msgid "Loading..."
@@ -768,192 +765,195 @@ msgstr "Đang tải..."
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Public server list is disabled"
-msgstr ""
+msgstr "Danh sách máy chủ công cộng bị tắt"
 
 #: builtin/mainmenu/serverlistmgr.lua
 msgid "Try reenabling public serverlist and check your internet connection."
 msgstr ""
-"Hãy thử kích hoạt lại danh sách máy chủ công cộng và kiểm tra kết nối "
-"internet của bạn."
+"Hãy thử kích hoạt lại danh sách máy chủ công cộng và kiểm tra kết nối mạng "
+"của bạn."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "Giới thiệu"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
-msgstr ""
+msgstr "Những người đóng góp tích cực"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active renderer:"
-msgstr ""
+msgstr "Trình kết xuất hiện hoạt:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
-msgstr ""
+msgstr "Các nhà phát triển cốt lõi"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Open User Data Directory"
-msgstr ""
+msgstr "Mở thư mục Dữ liệu người dùng"
 
 #: builtin/mainmenu/tab_about.lua
 msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"Mở thư mục chứa thế giới, trò chơi, bản mod do người dùng cung cấp\n"
+"và các gói kết cấu trong trình quản lý / trình khám phá tệp."
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
-msgstr ""
+msgstr "Những người đóng góp trước đây"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Core Developers"
-msgstr ""
+msgstr "Các nhà phát triển cốt lõi trước đây"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Browse online content"
-msgstr ""
+msgstr "Duyệt nội dung trực tuyến"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Content"
-msgstr ""
+msgstr "Nội dung"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Disable Texture Pack"
-msgstr ""
+msgstr "Tắt tất cả gói kết cấu"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Information:"
-msgstr ""
+msgstr "Thông tin:"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Installed Packages:"
-msgstr ""
+msgstr "Các gói đã cài đặt:"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "No dependencies."
-msgstr ""
+msgstr "Không có phần phụ thuộc nào."
 
 #: builtin/mainmenu/tab_content.lua
 msgid "No package description available"
-msgstr ""
+msgstr "Không có mô tả gói"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Rename"
-msgstr ""
+msgstr "Đổi tên"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Uninstall Package"
-msgstr ""
+msgstr "Gỡ cài đặt gói"
 
 #: builtin/mainmenu/tab_content.lua
 msgid "Use Texture Pack"
-msgstr ""
+msgstr "Dùng gói cấu hình này"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Announce Server"
-msgstr ""
+msgstr "Thông báo máy chủ"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Bind Address"
-msgstr ""
+msgstr "Địa chỉ bắt buộc"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Creative Mode"
-msgstr ""
+msgstr "Chế độ sáng tạo"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Enable Damage"
-msgstr ""
+msgstr "Kích hoạt sát thương"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Game"
-msgstr ""
+msgstr "Lưu trữ trò chơi"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Host Server"
-msgstr ""
+msgstr "Lưu trữ máy chủ"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Install games from ContentDB"
-msgstr ""
+msgstr "Cài đặt trò chơi từ ContentDB"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "Tên"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
-msgstr ""
+msgstr "Mới"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "No world created or selected!"
-msgstr ""
+msgstr "Không có thế giới nào được tạo ra hoặc được lựa chọn."
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Password"
-msgstr ""
+msgstr "Mật khẩu"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Play Game"
-msgstr ""
+msgstr "Chơi trò chơi"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Port"
-msgstr ""
+msgstr "Cổng"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select Mods"
-msgstr ""
+msgstr "Mod đã chọn"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Select World:"
-msgstr ""
+msgstr "Thế giới đã chọn:"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Server Port"
-msgstr ""
+msgstr "Cổng máy chủ"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "Start Game"
-msgstr ""
+msgstr "Bắt đầu trò chơi"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Address"
-msgstr ""
+msgstr "Địa chỉ"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
+#, fuzzy
 msgid "Clear"
-msgstr ""
+msgstr "Xóa"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Connect"
-msgstr ""
+msgstr "Kết nối"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Creative mode"
-msgstr ""
+msgstr "Chế độ sáng tạo"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
 msgid "Damage / PvP"
-msgstr ""
+msgstr "Sát thương / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
-msgstr ""
+msgstr "Xóa yêu thích"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Favorites"
-msgstr ""
+msgstr "Yêu thích"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "Máy chủ không tương thích"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
-msgstr ""
+msgstr "Tham gia trò chơi"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Ping"
@@ -961,15 +961,15 @@ msgstr ""
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Public Servers"
-msgstr ""
+msgstr "Máy chủ công cộng"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "Làm mới"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Server Description"
-msgstr ""
+msgstr "Mô tả Máy chủ"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "2x"
@@ -977,7 +977,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "3D Clouds"
-msgstr ""
+msgstr "Mây 3D"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "4x"
@@ -989,7 +989,7 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "All Settings"
-msgstr ""
+msgstr "Tất cả cài đặt"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Antialiasing:"
@@ -997,67 +997,71 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Autosave Screen Size"
-msgstr ""
+msgstr "Tự động lưu kích cỡ màn hình"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Bilinear Filter"
-msgstr ""
+msgstr "Bộ lọc song tuyến"
 
 #: builtin/mainmenu/tab_settings.lua src/client/game.cpp
 msgid "Change Keys"
-msgstr ""
+msgstr "Thay đổi khóa"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Connected Glass"
-msgstr ""
+msgstr "Kính đã kết nối"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Dynamic shadows"
-msgstr ""
+msgstr "Bóng kiểu động lực học"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "Bóng kiểu động lực học: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
-msgstr ""
+msgstr "Lá lạ mắt"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr "Cao"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr "Thấp"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr "Trung bình"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
 msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Mipmap + Aniso. Filter"
-msgstr ""
+msgstr "Mipmap + Bộ lọc Aniso."
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "No Filter"
-msgstr ""
+msgstr "Không bộ lọc"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "No Mipmap"
-msgstr ""
+msgstr "Không Mipmap"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Node Highlighting"
-msgstr ""
+msgstr "Đánh dấu node"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Node Outlining"
-msgstr ""
+msgstr "Phác thảo node"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "None"
@@ -1065,51 +1069,48 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Leaves"
-msgstr ""
+msgstr "Lá đục"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Opaque Water"
-msgstr ""
+msgstr "Nước đục"
 
 #: builtin/mainmenu/tab_settings.lua
+#, fuzzy
 msgid "Particles"
-msgstr ""
+msgstr "Vật rất nhỏ"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Screen:"
-msgstr ""
+msgstr "Màn hình:"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Settings"
-msgstr ""
+msgstr "Cài đặt"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Shaders"
-msgstr ""
+msgstr "Trình tạo bóng"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (experimental)"
-msgstr ""
+msgstr "Trình tạo bóng (đang trong thử nghiệm)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Shaders (unavailable)"
-msgstr ""
+msgstr "Trình tạo bóng (không tồn tại)"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Simple Leaves"
-msgstr ""
+msgstr "Lá đơn giản"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Smooth Lighting"
-msgstr ""
+msgstr "Ánh sáng mịn"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Texturing:"
-msgstr ""
-
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr ""
+msgstr "Cấu hình địa hình:"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
@@ -1121,166 +1122,202 @@ msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Trilinear Filter"
-msgstr ""
+msgstr "Bộ lọc tam song"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "Cực cao"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "Cực thấp"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
-msgstr ""
+msgstr "Lá sóng"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Liquids"
-msgstr ""
+msgstr "Nước chuyển động như sóng"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Plants"
-msgstr ""
+msgstr "Sinh vật chuyển động như sóng"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
-msgstr ""
+msgstr "Kết nối quá hạn."
 
 #: src/client/client.cpp
 msgid "Done!"
-msgstr ""
+msgstr "Đã xong!"
 
 #: src/client/client.cpp
+#, fuzzy
 msgid "Initializing nodes"
-msgstr ""
+msgstr "Đang khởi tạo các node"
 
 #: src/client/client.cpp
+#, fuzzy
 msgid "Initializing nodes..."
-msgstr ""
+msgstr "Đang khởi tạo các node..."
 
 #: src/client/client.cpp
 msgid "Loading textures..."
-msgstr ""
+msgstr "Đang tải cấu hình địa hình..."
 
 #: src/client/client.cpp
 msgid "Rebuilding shaders..."
-msgstr ""
+msgstr "Đang xây dựng lại trình tạo bóng..."
 
 #: src/client/clientlauncher.cpp
 msgid "Connection error (timed out?)"
-msgstr ""
+msgstr "Lỗi kết nối (hết thời gian chờ?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr ""
+msgid "Could not find or load game"
+msgstr "Không tìm thấy hoặc tải trò chơi: "
 
 #: src/client/clientlauncher.cpp
+#, fuzzy
 msgid "Invalid gamespec."
-msgstr ""
+msgstr "Gamespec không hợp lệ."
 
 #: src/client/clientlauncher.cpp
 msgid "Main Menu"
-msgstr ""
+msgstr "Màn hình chính"
 
 #: src/client/clientlauncher.cpp
 msgid "No world selected and no address provided. Nothing to do."
 msgstr ""
+"Không có thế giới nào được chọn và không có địa chỉ nào được cung cấp. Không "
+"có gì làm hết."
 
 #: src/client/clientlauncher.cpp
 msgid "Player name too long."
-msgstr ""
+msgstr "Tên người chơi quá dài."
 
 #: src/client/clientlauncher.cpp
 msgid "Please choose a name!"
-msgstr ""
+msgstr "Xin vui lòng chọn một tên người chơi!"
 
 #: src/client/clientlauncher.cpp
 msgid "Provided password file failed to open: "
-msgstr ""
+msgstr "Không mở được tệp mật khẩu được cung cấp: "
 
 #: src/client/clientlauncher.cpp
 msgid "Provided world path doesn't exist: "
-msgstr ""
+msgstr "Đường dẫn thế giới được cung cấp không tồn tại: "
 
 #: src/client/game.cpp
 msgid ""
 "\n"
 "Check debug.txt for details."
 msgstr ""
+"\n"
+"Hãy kiểm tra debug.txt để có thông tin chi tiết."
 
 #: src/client/game.cpp
 msgid "- Address: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr ""
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr ""
+msgstr "- Địa chỉ: "
 
 #: src/client/game.cpp
 msgid "- Mode: "
-msgstr ""
+msgstr "- Chế độ: "
 
 #: src/client/game.cpp
 msgid "- Port: "
-msgstr ""
+msgstr "- Cổng: "
 
 #: src/client/game.cpp
 msgid "- Public: "
-msgstr ""
+msgstr "- Công cộng: "
 
 #. ~ PvP = Player versus Player
 #: src/client/game.cpp
 msgid "- PvP: "
-msgstr ""
+msgstr "- PvP: "
 
 #: src/client/game.cpp
 msgid "- Server Name: "
-msgstr ""
+msgstr "- Tên máy chủ: "
+
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "Đã xảy ra lỗi tuần tự hóa:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "Quyền truy cập bị từ chối với lý do: %s"
 
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
-msgstr ""
+msgstr "Tự động chuyển tiếp bị tắt"
 
 #: src/client/game.cpp
 msgid "Automatic forward enabled"
-msgstr ""
+msgstr "Tự động chuyển tiếp đã bật"
+
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "Các ranh giới khối đã ẩn"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "Đã hiển thị ranh giới cho tất cả các khối"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "Đã hiển thị ranh giới hiển thị cho khối hiện tại"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "Đã hiển thị ranh giới cho các khối gần bạn"
 
 #: src/client/game.cpp
 msgid "Camera update disabled"
-msgstr ""
+msgstr "Cập nhật máy ảnh đã tắt"
 
 #: src/client/game.cpp
 msgid "Camera update enabled"
-msgstr ""
+msgstr "Cập nhật máy ảnh đã bật"
+
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "Không thể hiển thị giới hạn khối (vì phải có quyền 'basic_debug')"
 
 #: src/client/game.cpp
 msgid "Change Password"
-msgstr ""
+msgstr "Đổi mật khẩu"
 
 #: src/client/game.cpp
 msgid "Cinematic mode disabled"
-msgstr ""
+msgstr "Chế độ điện ảnh đã tắt"
 
 #: src/client/game.cpp
 msgid "Cinematic mode enabled"
-msgstr ""
+msgstr "Chế độ điện ảnh đã bật"
+
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "Máy khách đã ngắt kết nối"
 
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
-msgstr ""
+msgstr "Lập trình phía máy khách đã tắt"
 
 #: src/client/game.cpp
 msgid "Connecting to server..."
-msgstr ""
+msgstr "Đang kết nối tới máy chủ..."
+
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "Kết nối không thành công vì lý do không xác định"
 
 #: src/client/game.cpp
 msgid "Continue"
-msgstr ""
+msgstr "Tiếp tục"
 
 #: src/client/game.cpp
 #, c-format
@@ -1300,26 +1337,45 @@ msgid ""
 "- Mouse wheel: select item\n"
 "- %s: chat\n"
 msgstr ""
+"Điền khiển:\n"
+"- %s: tiến lên\n"
+"- %s: lùi về phía sau\n"
+"- %s: di chuyển sang trái\n"
+"- %s: di chuyển sang phải\n"
+"- %s: nhảy lên / leo lên\n"
+"- %s: đào / đấm\n"
+"- %s: địa điểm / sử dụng\n"
+"- %s: lẻn / leo xuống\n"
+"- %s: thả đồ\n"
+"- %s: khoảng không quảng cáo\n"
+"- Chuột: xoay / nhìn\n"
+"- Con lăn chuột: chọn đồ\n"
+"- %s: trò chuyện\n"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "Không thể giải mã địa chỉ: %s"
 
 #: src/client/game.cpp
 msgid "Creating client..."
-msgstr ""
+msgstr "Đang tạo máy khách..."
 
 #: src/client/game.cpp
 msgid "Creating server..."
-msgstr ""
+msgstr "Đang tạo máy chủ..."
 
 #: src/client/game.cpp
 msgid "Debug info and profiler graph hidden"
-msgstr ""
+msgstr "Thông tin gỡ lỗi và biểu đồ hồ sơ đã ẩn"
 
 #: src/client/game.cpp
 msgid "Debug info shown"
-msgstr ""
+msgstr "Thông tin gỡ lỗi đã hiển thị"
 
 #: src/client/game.cpp
 msgid "Debug info, profiler graph, and wireframe hidden"
-msgstr ""
+msgstr "Thông tin gỡ lỗi, biểu đồ hồ sơ và khung dây đã ẩn"
 
 #: src/client/game.cpp
 msgid ""
@@ -1336,66 +1392,78 @@ msgid ""
 "- touch&drag, tap 2nd finger\n"
 " --> place single item to slot\n"
 msgstr ""
+"Điều khiển mặc định:\n"
+"Không có menu nào hiển thị:\n"
+"- một lần nhấn: nút kích hoạt\n"
+"- nhấn đúp: đặt / sử dụng\n"
+"- trượt ngón tay: nhìn xung quanh\n"
+"Menu / khoảng không quảng cáo hiển thị:\n"
+"- nhấn đúp (bên ngoài):\n"
+" -> đóng\n"
+"- ngăn xếp cảm ứng, khe cắm cảm ứng:\n"
+" -> di chuyển ngăn xếp\n"
+"- chạm và kéo, chạm vào ngón tay thứ 2\n"
+" -> đặt một mục duy nhất vào vị trí\n"
 
 #: src/client/game.cpp
 msgid "Disabled unlimited viewing range"
-msgstr ""
+msgstr "Đã tắt phạm vi nhìn không giới hạn"
 
 #: src/client/game.cpp
 msgid "Enabled unlimited viewing range"
-msgstr ""
+msgstr "Đã bật phạm vi nhìn không giới hạn"
 
 #: src/client/game.cpp
 msgid "Exit to Menu"
-msgstr ""
+msgstr "Thoát ra màn hình chính"
 
 #: src/client/game.cpp
 msgid "Exit to OS"
-msgstr ""
+msgstr "Tắt Minetest"
 
 #: src/client/game.cpp
 msgid "Fast mode disabled"
-msgstr ""
+msgstr "Chế độ nhanh đã tắt"
 
 #: src/client/game.cpp
 msgid "Fast mode enabled"
-msgstr ""
+msgstr "Chế độ nhanh đã bật"
 
 #: src/client/game.cpp
 msgid "Fast mode enabled (note: no 'fast' privilege)"
-msgstr ""
+msgstr "Chế độ nhanh đã bật (ghi chú: không có ưu tiên cho 'nhanh')"
 
 #: src/client/game.cpp
 msgid "Fly mode disabled"
-msgstr ""
+msgstr "Chế độ bay đã tắt"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled"
-msgstr ""
+msgstr "Chế độ bay đã bật"
 
 #: src/client/game.cpp
 msgid "Fly mode enabled (note: no 'fly' privilege)"
-msgstr ""
+msgstr "Chế độ bay đã bật (ghi chú: không có ưu tiên cho 'bay')"
 
 #: src/client/game.cpp
 msgid "Fog disabled"
-msgstr ""
+msgstr "Sương mù đã tắt"
 
 #: src/client/game.cpp
 msgid "Fog enabled"
-msgstr ""
+msgstr "Sương mù đã bật"
 
 #: src/client/game.cpp
 msgid "Game info:"
-msgstr ""
+msgstr "Thông tin trò chơi:"
 
 #: src/client/game.cpp
 msgid "Game paused"
-msgstr ""
+msgstr "Trò chơi đã được tạm dừng"
 
 #: src/client/game.cpp
 msgid "Hosting server"
-msgstr ""
+msgstr "Đang tải máy chủ"
 
 #: src/client/game.cpp
 msgid "Item definitions..."
@@ -1403,7 +1471,7 @@ msgstr ""
 
 #: src/client/game.cpp
 msgid "KiB/s"
-msgstr ""
+msgstr "KiB/s"
 
 #: src/client/game.cpp
 msgid "Media..."
@@ -1493,6 +1561,21 @@ msgstr ""
 msgid "Sound unmuted"
 msgstr ""
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1827,6 +1910,14 @@ msgstr ""
 msgid "Minimap in texture mode"
 msgstr ""
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr ""
@@ -2022,7 +2113,8 @@ msgid "Muted"
 msgstr ""
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
+#, c-format
+msgid "Sound Volume: %d%%"
 msgstr ""
 
 #. ~ Imperative, as in "Enter/type in text".
@@ -2229,6 +2321,10 @@ msgid ""
 "screens."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2495,6 +2591,10 @@ msgstr ""
 msgid "Chat command time message threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
 msgstr ""
@@ -2528,7 +2628,7 @@ msgid "Chat toggle key"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
+msgid "Chat weblinks"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2547,6 +2647,12 @@ msgstr ""
 msgid "Clean transparent textures"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr ""
@@ -2622,6 +2728,22 @@ msgstr ""
 msgid "Command key"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr ""
@@ -2713,7 +2835,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
+"This also applies to the object crosshair."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -2732,7 +2854,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Damage"
-msgstr ""
+msgstr "Sát thương"
 
 #: src/settings_translation_file.cpp
 msgid "Debug info toggle key"
@@ -2790,8 +2912,8 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2909,6 +3031,10 @@ msgstr ""
 msgid "Disallow empty passwords"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr ""
@@ -2955,7 +3081,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -2981,14 +3114,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Enable players getting damage and dying."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
+msgstr "Cho phép người chơi nhận sát thương và chết."
 
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
@@ -3074,6 +3200,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr ""
@@ -3258,11 +3390,15 @@ msgid "Font size"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3271,6 +3407,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3330,10 +3477,6 @@ msgstr ""
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3382,7 +3525,7 @@ msgstr ""
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3814,7 +3957,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+msgid "Instrument chat commands on registration."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3898,7 +4041,7 @@ msgid "Joystick button repetition interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4727,7 +4870,7 @@ msgid "Map save interval"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -4893,6 +5036,9 @@ msgid ""
 "be queued.\n"
 "This should be lower than curl_parallel_limit."
 msgstr ""
+"Số lượt tải xuống đồng thời tối đa. Tải xuống vượt quá giới hạn sẽ được xếp "
+"hàng đợi.\n"
+"Giá trị này phải thấp hơn curl_parallel_limit."
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of forceloaded mapblocks."
@@ -5020,7 +5166,7 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+msgid "Modifies the size of the HUD elements."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5031,6 +5177,10 @@ msgstr ""
 msgid "Monospace font size"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr ""
@@ -5152,7 +5302,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 
@@ -5176,11 +5326,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5203,17 +5355,13 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5316,9 +5464,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5611,26 +5759,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5721,7 +5861,7 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5818,6 +5958,10 @@ msgid ""
 "(obviously, remote_media should end with a slash).\n"
 "Files that are not present will be fetched the usual way."
 msgstr ""
+"Chỉ định URL mà từ đó ứng dụng khách tìm phương tiện thay vì sử dụng UDP.\n"
+"$filename có thể truy cập được từ $remote_media$filename qua cURL\n"
+"(trong đó, remote_media phải kết thúc bằng dấu gạch chéo).\n"
+"Các tệp không có mặt sẽ được tìm theo cách thông thường."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -5826,6 +5970,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -5936,7 +6088,7 @@ msgstr ""
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -5954,7 +6106,7 @@ msgid "The URL for the content repository"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6023,7 +6175,7 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6116,6 +6268,10 @@ msgstr ""
 msgid "Touch screen threshold"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr ""
@@ -6186,7 +6342,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -6369,6 +6525,10 @@ msgstr ""
 msgid "Waving plants"
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -6390,7 +6550,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -6398,14 +6558,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -6421,7 +6574,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Whether to allow players to damage and kill each other."
-msgstr ""
+msgstr "Có cho phép người chơi sát thương và giết lẫn nhau hay không."
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6531,35 +6684,27 @@ msgstr ""
 msgid "Y-level of seabed."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
-msgstr ""
+msgstr "Hết thời gian chờ tải xuống tệp trong cURL"
 
 #: src/settings_translation_file.cpp
 msgid "cURL interactive timeout"
-msgstr ""
+msgstr "Hết thời gian tương tác với cURL"
 
 #: src/settings_translation_file.cpp
 msgid "cURL parallel limit"
-msgstr ""
+msgstr "Gặp giới hạn số lượng tệp tải xuống trong cURL"
+
+#~ msgid "- Creative Mode: "
+#~ msgstr "- Chế độ sáng tạo: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- Tổn hại: "
 
 #~ msgid "Ok"
 #~ msgstr "Được"
+
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "Bạn đã chết"
diff --git a/po/yue/minetest.po b/po/yue/minetest.po
new file mode 100644 (file)
index 0000000..45631b4
--- /dev/null
@@ -0,0 +1,6638 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the minetest package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: minetest\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: yue\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: builtin/client/chatcommands.lua
+msgid "Clear the out chat queue"
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Empty command."
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Exit to main menu"
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Invalid command: "
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Issued command: "
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "List online players"
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "Online players: "
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "The out chat queue is now empty."
+msgstr ""
+
+#: builtin/client/chatcommands.lua
+msgid "This command is disabled by server."
+msgstr ""
+
+#: builtin/client/death_formspec.lua src/client/game.cpp
+msgid "Respawn"
+msgstr ""
+
+#: builtin/client/death_formspec.lua src/client/game.cpp
+msgid "You died"
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "Available commands:"
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "Available commands: "
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "Command not available: "
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "Get help for commands"
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid ""
+"Use '.help <cmd>' to get more information, or '.help all' to list everything."
+msgstr ""
+
+#: builtin/common/chatcommands.lua
+msgid "[all | <cmd>]"
+msgstr ""
+
+#: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
+msgid "OK"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "An error occurred in a Lua script:"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "An error occurred:"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "Main menu"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "Reconnect"
+msgstr ""
+
+#: builtin/fstk/ui.lua
+msgid "The server has requested a reconnect:"
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "Protocol version mismatch. "
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "Server enforces protocol version $1. "
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "Server supports protocol versions between $1 and $2. "
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "We only support protocol version $1."
+msgstr ""
+
+#: builtin/mainmenu/common.lua
+msgid "We support protocol versions between version $1 and $2."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/dlg_create_world.lua
+#: builtin/mainmenu/dlg_delete_content.lua
+#: builtin/mainmenu/dlg_delete_world.lua
+#: builtin/mainmenu/dlg_rename_modpack.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua src/client/keycode.cpp
+#: src/gui/guiConfirmRegistration.cpp src/gui/guiKeyChangeMenu.cpp
+#: src/gui/guiPasswordChange.cpp
+msgid "Cancel"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/tab_content.lua
+msgid "Dependencies:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Disable all"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Disable modpack"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Enable all"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Enable modpack"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid ""
+"Failed to enable mod \"$1\" as it contains disallowed characters. Only "
+"characters [a-z0-9_] are allowed."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Find More Mods"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "Mod:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No (optional) dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No game description provided."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No hard dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No modpack description provided."
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "No optional dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua builtin/mainmenu/tab_content.lua
+msgid "Optional dependencies:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua src/gui/guiKeyChangeMenu.cpp
+msgid "Save"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "World:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_config_world.lua
+msgid "enabled"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "\"$1\" already exists. Would you like to overwrite it?"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 and $2 dependencies will be installed."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 by $2"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid ""
+"$1 downloading,\n"
+"$2 queued"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 downloading..."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 required dependencies could not be found."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "$1 will be installed, and $2 dependencies will be skipped."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "All packages"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Already installed"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Back to Main Menu"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Base Game:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "ContentDB is not available when Minetest was compiled without cURL"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Downloading..."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Failed to download $1"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Games"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install $1"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install missing dependencies"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Mods"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "No packages could be retrieved"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "No results"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "No updates"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Not found"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Overwrite"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Please check that the base game is correct."
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Queued"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Texture packs"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Uninstall"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Update"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Update All [$1]"
+msgstr ""
+
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "View more information in a web browser"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "A world named \"$1\" already exists"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Additional terrain"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Altitude chill"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Altitude dry"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Biome blending"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Biomes"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Caverns"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Caves"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Create"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Decorations"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Download a game, such as Minetest Game, from minetest.net"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Download one from minetest.net"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Dungeons"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Flat terrain"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Floating landmasses in the sky"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Floatlands (experimental)"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Game"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Generate non-fractal terrain: Oceans and underground"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Hills"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Humid rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Increases humidity around rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Lakes"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Low humidity and high heat causes shallow or dry rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Mapgen"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
+msgid "Mapgen flags"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Mapgen-specific flags"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Mountains"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Mud flow"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Network of tunnels and caves"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "No game selected"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Reduces heat with altitude"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Reduces humidity with altitude"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Sea level rivers"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Seed"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Smooth transition between biomes"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid ""
+"Structures appearing on the terrain (no effect on trees and jungle grass "
+"created by v6)"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Structures appearing on the terrain, typically trees and plants"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Temperate, Desert"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Temperate, Desert, Jungle"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Temperate, Desert, Jungle, Tundra, Taiga"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Terrain surface erosion"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Trees and jungle grass"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Vary river depth"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Very large caverns deep in the underground"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "Warning: The Development Test is meant for developers."
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "World name"
+msgstr ""
+
+#: builtin/mainmenu/dlg_create_world.lua
+msgid "You have no games installed."
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+msgid "Are you sure you want to delete \"$1\"?"
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+#: builtin/mainmenu/dlg_delete_world.lua builtin/mainmenu/tab_local.lua
+#: src/client/keycode.cpp
+msgid "Delete"
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+msgid "pkgmgr: failed to delete \"$1\""
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_content.lua
+msgid "pkgmgr: invalid path \"$1\""
+msgstr ""
+
+#: builtin/mainmenu/dlg_delete_world.lua
+msgid "Delete World \"$1\"?"
+msgstr ""
+
+#: builtin/mainmenu/dlg_rename_modpack.lua
+msgid "Accept"
+msgstr ""
+
+#: builtin/mainmenu/dlg_rename_modpack.lua
+msgid "Rename Modpack:"
+msgstr ""
+
+#: builtin/mainmenu/dlg_rename_modpack.lua
+msgid ""
+"This modpack has an explicit name given in its modpack.conf which will "
+"override any renaming here."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "(No description of setting given)"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "2D Noise"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "< Back to Settings page"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Browse"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_settings.lua
+msgid "Disabled"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Edit"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Enabled"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Lacunarity"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Octaves"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
+msgid "Offset"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Persistence"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Please enter a valid integer."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Please enter a valid number."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Restore Default"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua src/settings_translation_file.cpp
+msgid "Scale"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua builtin/mainmenu/tab_online.lua
+msgid "Search"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Select directory"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Select file"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Show technical names"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "The value must be at least $1."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "The value must not be larger than $1."
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "X"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "X spread"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Y"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Y spread"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Z"
+msgstr ""
+
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "Z spread"
+msgstr ""
+
+#. ~ "absvalue" is a noise parameter flag.
+#. It is short for "absolute value".
+#. It can be enabled in noise settings in
+#. main menu -> "All Settings".
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "absvalue"
+msgstr ""
+
+#. ~ "defaults" is a noise parameter flag.
+#. It describes the default processing options
+#. for noise settings in main menu -> "All Settings".
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "defaults"
+msgstr ""
+
+#. ~ "eased" is a noise parameter flag.
+#. It is used to make the map smoother and
+#. can be enabled in noise settings in
+#. main menu -> "All Settings".
+#: builtin/mainmenu/dlg_settings_advanced.lua
+msgid "eased"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "$1 (Enabled)"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "$1 mods"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Failed to install $1 to $2"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Install Mod: Unable to find real mod name for: $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Install Mod: Unable to find suitable folder name for modpack $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to find a valid mod or modpack"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a $1 as a texture pack"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a game as a $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a mod as a $1"
+msgstr ""
+
+#: builtin/mainmenu/pkgmgr.lua
+msgid "Unable to install a modpack as a $1"
+msgstr ""
+
+#: builtin/mainmenu/serverlistmgr.lua src/client/game.cpp
+msgid "Loading..."
+msgstr ""
+
+#: builtin/mainmenu/serverlistmgr.lua
+msgid "Public server list is disabled"
+msgstr ""
+
+#: builtin/mainmenu/serverlistmgr.lua
+msgid "Try reenabling public serverlist and check your internet connection."
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "About"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Active Contributors"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Active renderer:"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Core Developers"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Open User Data Directory"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid ""
+"Opens the directory that contains user-provided worlds, games, mods,\n"
+"and texture packs in a file manager / explorer."
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Previous Contributors"
+msgstr ""
+
+#: builtin/mainmenu/tab_about.lua
+msgid "Previous Core Developers"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Browse online content"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Content"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Disable Texture Pack"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Information:"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Installed Packages:"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "No dependencies."
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "No package description available"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Rename"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Uninstall Package"
+msgstr ""
+
+#: builtin/mainmenu/tab_content.lua
+msgid "Use Texture Pack"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Announce Server"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Bind Address"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Creative Mode"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Enable Damage"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Host Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Host Server"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Install games from ContentDB"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
+msgid "Name"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "New"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "No world created or selected!"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
+msgid "Password"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Play Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
+msgid "Port"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Select Mods"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Select World:"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Server Port"
+msgstr ""
+
+#: builtin/mainmenu/tab_local.lua
+msgid "Start Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Address"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
+msgid "Clear"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Connect"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Creative mode"
+msgstr ""
+
+#. ~ PvP = Player versus Player
+#: builtin/mainmenu/tab_online.lua
+msgid "Damage / PvP"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Del. Favorite"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Favorites"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Incompatible Servers"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Join Game"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Ping"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Public Servers"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Refresh"
+msgstr ""
+
+#: builtin/mainmenu/tab_online.lua
+msgid "Server Description"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "2x"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "3D Clouds"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "4x"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "8x"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "All Settings"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Antialiasing:"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Autosave Screen Size"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Bilinear Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/client/game.cpp
+msgid "Change Keys"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Connected Glass"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
+msgid "Dynamic shadows"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Dynamic shadows: "
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Fancy Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "High"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Low"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Medium"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Mipmap"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Mipmap + Aniso. Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "No Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "No Mipmap"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Node Highlighting"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Node Outlining"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "None"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Opaque Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Opaque Water"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Particles"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Screen:"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Settings"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
+msgid "Shaders"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Shaders (experimental)"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Shaders (unavailable)"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Simple Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Smooth Lighting"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Texturing:"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
+msgid "Tone Mapping"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Touchthreshold: (px)"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Trilinear Filter"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Ultra High"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Very Low"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Waving Leaves"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Waving Liquids"
+msgstr ""
+
+#: builtin/mainmenu/tab_settings.lua
+msgid "Waving Plants"
+msgstr ""
+
+#: src/client/client.cpp src/client/game.cpp
+msgid "Connection timed out."
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Done!"
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Initializing nodes"
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Initializing nodes..."
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Loading textures..."
+msgstr ""
+
+#: src/client/client.cpp
+msgid "Rebuilding shaders..."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Connection error (timed out?)"
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Could not find or load game: "
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Invalid gamespec."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Main Menu"
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "No world selected and no address provided. Nothing to do."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Player name too long."
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Please choose a name!"
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Provided password file failed to open: "
+msgstr ""
+
+#: src/client/clientlauncher.cpp
+msgid "Provided world path doesn't exist: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid ""
+"\n"
+"Check debug.txt for details."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Address: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Mode: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Port: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Public: "
+msgstr ""
+
+#. ~ PvP = Player versus Player
+#: src/client/game.cpp
+msgid "- PvP: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "- Server Name: "
+msgstr ""
+
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Automatic forward disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Automatic forward enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Camera update disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Camera update enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Change Password"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Cinematic mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Cinematic mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Client side scripting is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Connecting to server..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Continue"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid ""
+"Controls:\n"
+"- %s: move forwards\n"
+"- %s: move backwards\n"
+"- %s: move left\n"
+"- %s: move right\n"
+"- %s: jump/climb up\n"
+"- %s: dig/punch\n"
+"- %s: place/use\n"
+"- %s: sneak/climb down\n"
+"- %s: drop item\n"
+"- %s: inventory\n"
+"- Mouse: turn/look\n"
+"- Mouse wheel: select item\n"
+"- %s: chat\n"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Creating client..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Creating server..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Debug info and profiler graph hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Debug info shown"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Debug info, profiler graph, and wireframe hidden"
+msgstr ""
+
+#: src/client/game.cpp
+msgid ""
+"Default Controls:\n"
+"No menu visible:\n"
+"- single tap: button activate\n"
+"- double tap: place/use\n"
+"- slide finger: look around\n"
+"Menu/Inventory visible:\n"
+"- double tap (outside):\n"
+" -->close\n"
+"- touch stack, touch slot:\n"
+" --> move stack\n"
+"- touch&drag, tap 2nd finger\n"
+" --> place single item to slot\n"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Disabled unlimited viewing range"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Enabled unlimited viewing range"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Exit to Menu"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Exit to OS"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fast mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fast mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fast mode enabled (note: no 'fast' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fly mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fly mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fly mode enabled (note: no 'fly' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fog disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Fog enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Game info:"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Game paused"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Hosting server"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Item definitions..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "KiB/s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Media..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "MiB/s"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Minimap currently disabled by game or mod"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Multiplayer"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Noclip mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Noclip mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Noclip mode enabled (note: no 'noclip' privilege)"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Node definitions..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Off"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "On"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Pitch move mode disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Pitch move mode enabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Profiler graph shown"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Remote server"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Resolving address..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Shutting down..."
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Singleplayer"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound Volume"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound muted"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound system is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound system is not supported on this build"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Sound unmuted"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Viewing range changed to %d"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Viewing range is at maximum: %d"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Viewing range is at minimum: %d"
+msgstr ""
+
+#: src/client/game.cpp
+#, c-format
+msgid "Volume changed to %d%%"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Wireframe shown"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Zoom currently disabled by game or mod"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "ok"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "Chat hidden"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "Chat shown"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "HUD hidden"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "HUD shown"
+msgstr ""
+
+#: src/client/gameui.cpp
+msgid "Profiler hidden"
+msgstr ""
+
+#: src/client/gameui.cpp
+#, c-format
+msgid "Profiler shown (page %d of %d)"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Apps"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Backspace"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Caps Lock"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Control"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Down"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "End"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Erase EOF"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Execute"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Help"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Home"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Accept"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Convert"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Escape"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Mode Change"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "IME Nonconvert"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Insert"
+msgstr ""
+
+#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
+msgid "Left"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Button"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Control"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Menu"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Shift"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Left Windows"
+msgstr ""
+
+#. ~ Key name, common on Windows keyboards
+#: src/client/keycode.cpp
+msgid "Menu"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Middle Button"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Num Lock"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad *"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad +"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad -"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad ."
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad /"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 0"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 1"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 2"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 3"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 4"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 5"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 6"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 7"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 8"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Numpad 9"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "OEM Clear"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Page down"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Page up"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Pause"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Play"
+msgstr ""
+
+#. ~ "Print screen" key
+#: src/client/keycode.cpp
+msgid "Print"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Return"
+msgstr ""
+
+#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
+msgid "Right"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Button"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Control"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Menu"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Shift"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Right Windows"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Scroll Lock"
+msgstr ""
+
+#. ~ Key name
+#: src/client/keycode.cpp
+msgid "Select"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Shift"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Sleep"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Snapshot"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Space"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Tab"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "Up"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "X Button 1"
+msgstr ""
+
+#: src/client/keycode.cpp
+msgid "X Button 2"
+msgstr ""
+
+#: src/client/keycode.cpp src/gui/guiKeyChangeMenu.cpp
+msgid "Zoom"
+msgstr ""
+
+#: src/client/minimap.cpp
+msgid "Minimap hidden"
+msgstr ""
+
+#: src/client/minimap.cpp
+#, c-format
+msgid "Minimap in radar mode, Zoom x%d"
+msgstr ""
+
+#: src/client/minimap.cpp
+#, c-format
+msgid "Minimap in surface mode, Zoom x%d"
+msgstr ""
+
+#: src/client/minimap.cpp
+msgid "Minimap in texture mode"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr ""
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr ""
+
+#: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
+msgid "Passwords do not match!"
+msgstr ""
+
+#: src/gui/guiConfirmRegistration.cpp
+msgid "Register and Join"
+msgstr ""
+
+#: src/gui/guiConfirmRegistration.cpp
+#, c-format
+msgid ""
+"You are about to join this server with the name \"%s\" for the first time.\n"
+"If you proceed, a new account using your credentials will be created on this "
+"server.\n"
+"Please retype your password and click 'Register and Join' to confirm account "
+"creation, or click 'Cancel' to abort."
+msgstr ""
+
+#: src/gui/guiFormSpecMenu.cpp
+msgid "Proceed"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "\"Aux1\" = climb down"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Autoforward"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
+msgid "Automatic jumping"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Aux1"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Backward"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Block bounds"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Change camera"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Chat"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Command"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Console"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Dec. range"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Dec. volume"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Double tap \"jump\" to toggle fly"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Drop"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Forward"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Inc. range"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Inc. volume"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Inventory"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Jump"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Key already in use"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Local command"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Mute"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Next item"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Prev. item"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Range select"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp src/settings_translation_file.cpp
+msgid "Screenshot"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Sneak"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle HUD"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle chat log"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle fast"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle fly"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle fog"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle minimap"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle noclip"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "Toggle pitchmove"
+msgstr ""
+
+#: src/gui/guiKeyChangeMenu.cpp
+msgid "press key"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "Change"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "Confirm Password"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "New Password"
+msgstr ""
+
+#: src/gui/guiPasswordChange.cpp
+msgid "Old Password"
+msgstr ""
+
+#: src/gui/guiVolumeChange.cpp
+msgid "Exit"
+msgstr ""
+
+#: src/gui/guiVolumeChange.cpp
+msgid "Muted"
+msgstr ""
+
+#: src/gui/guiVolumeChange.cpp
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr ""
+
+#. ~ Imperative, as in "Enter/type in text".
+#. Don't forget the space.
+#: src/gui/modalMenu.cpp
+msgid "Enter "
+msgstr ""
+
+#. ~ DO NOT TRANSLATE THIS LITERALLY!
+#. This is a special string which needs to contain the translation's
+#. language code (e.g. "de" for German).
+#: src/network/clientpackethandler.cpp src/script/lua_api/l_client.cpp
+msgid "LANG_CODE"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(Android) Fixes the position of virtual joystick.\n"
+"If disabled, virtual joystick will center to first-touch's position."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
+"If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
+"circle."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(X,Y,Z) offset of fractal from world center in units of 'scale'.\n"
+"Can be used to move a desired point to (0, 0) to create a\n"
+"suitable spawn point, or to allow 'zooming in' on a desired\n"
+"point by increasing 'scale'.\n"
+"The default is tuned for a suitable spawn point for Mandelbrot\n"
+"sets with default parameters, it may need altering in other\n"
+"situations.\n"
+"Range roughly -2 to 2. Multiply by 'scale' for offset in nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"(X,Y,Z) scale of fractal in nodes.\n"
+"Actual fractal size will be 2 to 3 times larger.\n"
+"These numbers can be made very large, the fractal does\n"
+"not have to fit inside the world.\n"
+"Increase these to 'zoom' into the detail of the fractal.\n"
+"Default is for a vertically-squashed shape suitable for\n"
+"an island, set all 3 numbers equal for the raw shape."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the shape/size of ridged mountains."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the shape/size of rolling hills."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the shape/size of step mountains."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the size/occurrence of ridged mountain ranges."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the size/occurrence of rolling hills."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that controls the size/occurrence of step mountain ranges."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "2D noise that locates the river valleys and channels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D clouds"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D mode parallax strength"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise defining giant caverns."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"3D noise defining mountain structure and height.\n"
+"Also defines structure of floatland mountain terrain."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"3D noise defining structure of floatlands.\n"
+"If altered from the default, the noise 'scale' (0.7 by default) may need\n"
+"to be adjusted, as floatland tapering functions best when this noise has\n"
+"a value range of approximately -2.0 to 2.0."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise defining structure of river canyon walls."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise defining terrain."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise for mountain overhangs, cliffs, etc. Usually small variations."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "3D noise that determines number of dungeons per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"3D support.\n"
+"Currently supported:\n"
+"-    none: no 3d output.\n"
+"-    anaglyph: cyan/magenta color 3d.\n"
+"-    interlaced: odd/even line based polarisation screen support.\n"
+"-    topbottom: split screen top/bottom.\n"
+"-    sidebyside: split screen side by side.\n"
+"-    crossview: Cross-eyed 3d\n"
+"-    pageflip: quadbuffer based 3d.\n"
+"Note that the interlaced mode requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"A chosen map seed for a new map, leave empty for random.\n"
+"Will be overridden when creating a new world in the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "A message to be displayed to all clients when the server crashes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "A message to be displayed to all clients when the server shuts down."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ABM interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ABM time budget"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Absolute limit of queued blocks to emerge"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Acceleration in air"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Acceleration of gravity, in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active Block Modifiers"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active block management interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active block range"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Active object send range"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Address to connect to.\n"
+"Leave this blank to start a local server.\n"
+"Note that the address field in the main menu overrides this setting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Adds particles when digging a node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k "
+"screens."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, c-format
+msgid ""
+"Adjusts the density of the floatland layer.\n"
+"Increase value to increase density. Can be positive or negative.\n"
+"Value = 0.0: 50% of volume is floatland.\n"
+"Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test\n"
+"to be sure) creates a solid floatland layer."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Advanced"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Alters the light curve by applying 'gamma correction' to it.\n"
+"Higher values make middle and lower light levels brighter.\n"
+"Value '1.0' leaves the light curve unaltered.\n"
+"This only has significant effect on daylight and artificial\n"
+"light, it has very little effect on natural night light."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Always fly and fast"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ambient occlusion gamma"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Amount of messages a player may send per 10 seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Amplifies the valleys."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Anisotropic filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Announce server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Announce to this serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Append item name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Append item name to tooltip."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Apple trees noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Arm inertia"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Arm inertia, gives a more realistic movement of\n"
+"the arm when the camera moves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ask to reconnect after crash"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"At this distance the server will aggressively optimize which blocks are sent "
+"to\n"
+"clients.\n"
+"Small values potentially improve performance a lot, at the expense of "
+"visible\n"
+"rendering glitches (some blocks will not be rendered under water and in "
+"caves,\n"
+"as well as sometimes on land).\n"
+"Setting this to a value greater than max_block_send_distance disables this\n"
+"optimization.\n"
+"Stated in mapblocks (16 nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Automatic forward key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Automatically jump up single-node obstacles."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Automatically report to the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Autosave screen size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Autoscaling mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Aux1 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Aux1 key for climbing/descending"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Backward key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Base ground level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Base terrain height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Basic"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Basic privileges"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Beach noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Beach noise threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bilinear filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bind address"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Biome API temperature and humidity noise parameters"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Biome noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Block send optimize distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold and italic font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold and italic monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Bold monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Build inside player"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Builtin"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Camera 'near clipping plane' distance in nodes, between 0 and 0.25\n"
+"Only works on GLES platforms. Most users will not need to change this.\n"
+"Increasing can reduce artifacting on weaker GPUs.\n"
+"0.1 = Default, 0.25 = Good value for weaker tablets."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Camera smoothing"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Camera smoothing in cinematic mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Camera update toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave noise #1"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave noise #2"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave1 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cave2 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern taper"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cavern upper limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Center of light curve boost range.\n"
+"Where 0.0 is minimum light level, 1.0 is maximum light level."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat command time message threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat font size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat log level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message count limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message format"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message kick threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat message max length"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chat weblinks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Chunk size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cinematic mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cinematic mode key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clean transparent textures"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client and Server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client modding"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client side modding restrictions"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Client side node lookup range restriction"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Climbing speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Cloud radius"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clouds"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clouds are a client side effect."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Clouds in menu"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Colored fog"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Colored shadows"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Comma-separated list of flags to hide in the content repository.\n"
+"\"nonfree\" can be used to hide packages which do not qualify as 'free "
+"software',\n"
+"as defined by the Free Software Foundation.\n"
+"You can also specify content ratings.\n"
+"These flags are independent from Minetest versions,\n"
+"so see a full list at https://content.minetest.net/help/content_flags/"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Comma-separated list of mods that are allowed to access HTTP APIs, which\n"
+"allow them to upload and download data to/from the internet."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Comma-separated list of trusted mods that are allowed to access insecure\n"
+"functions even when mod security is on (via request_insecure_environment())."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Command key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Connect glass"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Connect to external media server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Connects glass if supported by node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Console alpha"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Console color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Console height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ContentDB Flag Blacklist"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ContentDB Max Concurrent Downloads"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "ContentDB URL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Continuous forward"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Continuous forward movement, toggled by autoforward key.\n"
+"Press the autoforward key again or the backwards movement to disable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Controls length of day/night cycle.\n"
+"Examples:\n"
+"72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls sinking speed in liquid."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls steepness/depth of lake depressions."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Controls steepness/height of hills."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Controls width of tunnels, a smaller value creates wider tunnels.\n"
+"Value >= 10.0 completely disables generation of tunnels and avoids the\n"
+"intensive noise calculations."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Crash message"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Creative"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Crosshair alpha"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Crosshair alpha (opaqueness, between 0 and 255).\n"
+"This also applies to the object crosshair."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Crosshair color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Crosshair color (R,G,B).\n"
+"Also controls the object crosshair color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Damage"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Debug info toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Debug log file size threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Debug log level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dec. volume key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Decrease this to increase liquid resistance to movement."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dedicated server step"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default acceleration"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default game"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Default game when creating a new world.\n"
+"This will be overridden when creating a world from the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default password"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default privileges"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default report format"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Default stack size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
+"but also uses more resources."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines areas where trees have apples."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines areas with sandy beaches."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines distribution of higher terrain and steepness of cliffs."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines distribution of higher terrain."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines full size of caverns, smaller values create larger caverns."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines large-scale river channel structure."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines location and terrain of optional hills and lakes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the base ground level."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the depth of the river channel."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the width of the river channel."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines the width of the river valley."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Defines tree areas and tree density."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Delay between mesh updates on the client in ms. Increasing this will slow\n"
+"down the rate of mesh updates, thus reducing jitter on slower clients."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Delay in sending blocks after building"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Delay showing tooltips, stated in milliseconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Deprecated Lua API handling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Depth below which you'll find giant caverns."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Depth below which you'll find large caves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Description of server, to be displayed when players join and in the "
+"serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Desert noise threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Deserts occur when np_biome exceeds this value.\n"
+"When the 'snowbiomes' flag is enabled, this is ignored."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Desynchronize block animation"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dig key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Digging particles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Disable anticheat"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Disallow empty passwords"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Domain name of server, to be displayed in the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Double tap jump for fly"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Double-tapping the jump key toggles fly mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Drop item key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dump the mapgen debug information."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dungeon maximum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dungeon minimum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Dungeon noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable IPv6 support (for both client and server).\n"
+"Required for IPv6 connections to work at all."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable Lua modding support on client.\n"
+"This support is experimental and API can change."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
+"On true translucent nodes cast colored shadows. This is expensive."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable console window"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable creative mode for all players"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable joysticks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable mod channels support."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable mod security"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable players getting damage and dying."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable random user input (only used for testing)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enable register confirmation"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable register confirmation when connecting to server.\n"
+"If disabled, new account will be registered automatically."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable smooth lighting with simple ambient occlusion.\n"
+"Disable for speed or for different looks."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable to disallow old clients from connecting.\n"
+"Older clients are compatible in the sense that they will not crash when "
+"connecting\n"
+"to new servers, but they may not support all new features that you are "
+"expecting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable usage of remote media server (if provided by server).\n"
+"Remote servers offer a significantly faster way to download media (e.g. "
+"textures)\n"
+"when connecting to the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable vertex buffer objects.\n"
+"This should greatly improve graphics performance."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable view bobbing and amount of view bobbing.\n"
+"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable/disable running an IPv6 server.\n"
+"Ignored if bind_address is set.\n"
+"Needs enable_ipv6 to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables Hable's 'Uncharted 2' filmic tone mapping.\n"
+"Simulates the tone curve of photographic film and how this approximates the\n"
+"appearance of high dynamic range images. Mid-range contrast is slightly\n"
+"enhanced, highlights and shadows are gradually compressed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enables animation of inventory items."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enables caching of facedir rotated meshes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Enables minimap."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables the sound system.\n"
+"If disabled, this completely disables all sounds everywhere and the in-game\n"
+"sound controls will be non-functional.\n"
+"Changing this setting requires a restart."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Engine profiling data print interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Entity methods"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Exponent of the floatland tapering. Alters the tapering behaviour.\n"
+"Value = 1.0 creates a uniform, linear tapering.\n"
+"Values > 1.0 create a smooth tapering suitable for the default separated\n"
+"floatlands.\n"
+"Values < 1.0 (for example 0.25) create a more defined surface level with\n"
+"flatter lowlands, suitable for a solid floatland layer."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "FPS when unfocused or paused"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "FSAA"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Factor noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fall bobbing factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fallback font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast mode acceleration"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast mode speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fast movement"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Fast movement (via the \"Aux1\" key).\n"
+"This requires the \"fast\" privilege on the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Field of view"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Field of view in degrees."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"File in client/serverlist/ that contains your favorite servers displayed in "
+"the\n"
+"Multiplayer Tab."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filler depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filler depth noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filmic tone mapping"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Filtered textures can blend RGB values with fully-transparent neighbors,\n"
+"which PNG optimizers usually discard, often resulting in dark or\n"
+"light edges to transparent textures. Apply a filter to clean that up\n"
+"at texture load time. This is automatically enabled if mipmapping is enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "First of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "First of two 3D noises that together define tunnels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fixed map seed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fixed virtual joystick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland density"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland maximum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland minimum Y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland taper exponent"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland tapering distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Floatland water level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fly key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Flying"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fog"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fog start"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fog toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font bold by default"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font italic by default"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font shadow"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font shadow alpha"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Font size of the recent chat text and chat prompt in point (pt).\n"
+"Value 0 will use the default font size."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Format of player chat messages. The following strings are valid "
+"placeholders:\n"
+"@name, @message, @timestamp (optional)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Format of screenshots."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Default Background Color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Default Background Opacity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Full-Screen Background Color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec Full-Screen Background Opacity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec default background color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec default background opacity (between 0 and 255)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec full-screen background color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Formspec full-screen background opacity (between 0 and 255)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Forward key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fourth of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fractal type"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fraction of the visible distance at which fog starts to be rendered"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"From how far blocks are generated for clients, stated in mapblocks (16 "
+"nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"From how far blocks are sent to clients, stated in mapblocks (16 nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"From how far clients know about objects, stated in mapblocks (16 nodes).\n"
+"\n"
+"Setting this larger than active_block_range will also cause the server\n"
+"to maintain active objects up to this distance in the direction the\n"
+"player is looking. (This can avoid mobs suddenly disappearing from view)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Full screen"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Fullscreen mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "GUI scaling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "GUI scaling filter"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "GUI scaling filter txr2img"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Global callbacks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Global map generation attributes.\n"
+"In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
+"and jungle grass, in all other mapgens this flag controls all decorations."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Gradient of light curve at maximum light level.\n"
+"Controls the contrast of the highest light levels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Gradient of light curve at minimum light level.\n"
+"Controls the contrast of the lowest light levels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Graphics"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Gravity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ground level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ground noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "HTTP mods"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "HUD scale factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "HUD toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Handling for deprecated Lua API calls:\n"
+"-    none: Do not log deprecated calls\n"
+"-    log: mimic and log backtrace of deprecated call (default).\n"
+"-    error: abort on usage of deprecated call (suggested for mod developers)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Have the profiler instrument itself:\n"
+"* Instrument an empty function.\n"
+"This estimates the overhead, that instrumentation is adding (+1 function "
+"call).\n"
+"* Instrument the sampler being used to update the statistics."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Heat blend noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Heat noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Height component of the initial window size. Ignored in fullscreen mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Height noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Height select noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hill steepness"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hill threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness1 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness2 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness3 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hilliness4 noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Homepage of server, to be displayed in the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Horizontal acceleration in air when jumping or falling,\n"
+"in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Horizontal and vertical acceleration in fast mode,\n"
+"in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Horizontal and vertical acceleration on ground or when climbing,\n"
+"in nodes per second per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar next key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar previous key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 1 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 10 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 11 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 12 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 13 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 14 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 15 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 16 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 17 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 18 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 19 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 2 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 20 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 21 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 22 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 23 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 24 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 25 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 26 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 27 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 28 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 29 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 3 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 30 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 31 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 32 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 4 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 5 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 6 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 7 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 8 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Hotbar slot 9 key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "How deep to make rivers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"How fast liquid waves will move. Higher = faster.\n"
+"If negative, liquid waves will move backwards.\n"
+"Requires waving liquids to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"How much the server will wait before unloading unused mapblocks.\n"
+"Higher value is smoother, but will use more RAM."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "How wide to make rivers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Humidity blend noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Humidity noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Humidity variation for biomes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "IPv6"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "IPv6 server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If FPS would go higher than this, limit it by sleeping\n"
+"to not waste CPU power for no benefit."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
+"enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled the server will perform map block occlusion culling based on\n"
+"on the eye position of the player. This can reduce the number of blocks\n"
+"sent to the client 50-80%. The client will not longer receive most "
+"invisible\n"
+"so that the utility of noclip mode is reduced."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled together with fly mode, player is able to fly through solid "
+"nodes.\n"
+"This requires the \"noclip\" privilege on the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
+"and\n"
+"descending."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, actions are recorded for rollback.\n"
+"This option is only read when server starts."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "If enabled, disable cheat prevention in multiplayer."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, invalid world data won't cause the server to shut down.\n"
+"Only enable this if you know what you are doing."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, makes move directions relative to the player's pitch when flying "
+"or swimming."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "If enabled, new players cannot join with an empty password."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If enabled, you can place blocks at the position (feet + eye level) where "
+"you stand.\n"
+"This is helpful when working with nodeboxes in small areas."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If the CSM restriction for node range is enabled, get_node calls are "
+"limited\n"
+"to this distance from the player to the node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If the execution of a chat command takes longer than this specified time in\n"
+"seconds, add the time information to the chat command message"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"If the file size of debug.txt exceeds the number of megabytes specified in\n"
+"this setting when it is opened, the file is moved to debug.txt.1,\n"
+"deleting an older debug.txt.1 if it exists.\n"
+"debug.txt is only moved if this setting is positive."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "If this is set, players will always (re)spawn at the given position."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ignore world errors"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-Game"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-game chat console background alpha (opaqueness, between 0 and 255)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-game chat console background color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "In-game chat console height, between 0.1 (10%) and 1.0 (100%)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Inc. volume key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Initial vertical speed when jumping, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument builtin.\n"
+"This is usually only needed by core/builtin contributors"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Instrument chat commands on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument global callback functions on registration.\n"
+"(anything you pass to a minetest.register_*() function)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument the action function of Active Block Modifiers on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Instrument the action function of Loading Block Modifiers on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Instrument the methods of entities on registration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Instrumentation"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Interval of saving important changes in the world, stated in seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Interval of sending time of day to clients."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Inventory items animations"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Inventory key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Invert mouse"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Invert vertical mouse movement."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Italic font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Italic monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Item entity TTL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Iterations"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Iterations of the recursive function.\n"
+"Increasing this increases the amount of fine detail, but also\n"
+"increases processing load.\n"
+"At iterations = 20 this mapgen has a similar load to mapgen V7."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick ID"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick button repetition interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick dead zone"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick frustum sensitivity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Joystick type"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"W component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Has no effect on 3D fractals.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"X component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"Y component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Julia set only.\n"
+"Z component of hypercomplex constant.\n"
+"Alters the shape of the fractal.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia w"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia x"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia y"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Julia z"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Jump key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Jumping speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for decreasing the viewing range.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for decreasing the volume.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for digging.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for dropping the currently selected item.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for increasing the viewing range.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for increasing the volume.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for jumping.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving fast in fast mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player backward.\n"
+"Will also disable autoforward, when active.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player forward.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player left.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for moving the player right.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for muting the game.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the chat window to type commands.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the chat window to type local commands.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the chat window.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for opening the inventory.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for placing.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 11th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 12th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 13th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 14th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 15th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 16th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 17th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 18th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 19th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 20th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 21st hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 22nd hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 23rd hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 24th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 25th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 26th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 27th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 28th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 29th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 30th hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 31st hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the 32nd hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the eighth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the fifth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the first hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the fourth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the next item in the hotbar.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the ninth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the previous item in the hotbar.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the second hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the seventh hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the sixth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the tenth hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for selecting the third hotbar slot.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for sneaking.\n"
+"Also used for climbing down and descending in water if aux1_descends is "
+"disabled.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for switching between first- and third-person camera.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for taking screenshots.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling autoforward.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling cinematic mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling display of minimap.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling fast mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling flying.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling noclip mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling pitch move mode.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the camera update. Only used for development\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of chat.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of debug info.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of fog.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of the HUD.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of the large chat console.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling the display of the profiler. Used for development.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key for toggling unlimited view range.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Key to use view zoom when possible.\n"
+"See http://irrlicht.sourceforge.net/docu/namespaceirr."
+"html#a54da2a0e231901735e3da1b0edf72eb3"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Kick players who sent more than X messages per 10 seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lake steepness"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lake threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Language"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave maximum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave minimum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large cave proportion flooded"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Large chat console key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Leaves style"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Leaves style:\n"
+"-   Fancy:  all faces visible\n"
+"-   Simple: only outer faces, if defined special_tiles are used\n"
+"-   Opaque: disable transparency"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Left key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Length of a server tick and the interval at which objects are generally "
+"updated over\n"
+"network."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Length of liquid waves.\n"
+"Requires waving liquids to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Length of time between Active Block Modifier (ABM) execution cycles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Length of time between NodeTimer execution cycles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Length of time between active block management cycles"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Level of logging to be written to debug.txt:\n"
+"-    <nothing> (no logging)\n"
+"-    none (messages with no level)\n"
+"-    error\n"
+"-    warning\n"
+"-    action\n"
+"-    info\n"
+"-    verbose"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve boost"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve boost center"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve boost spread"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve gamma"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve high gradient"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Light curve low gradient"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\n"
+"Only mapchunks completely within the mapgen limit are generated.\n"
+"Value is stored per-world."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Limits number of parallel HTTP requests. Affects:\n"
+"-    Media fetch if server uses remote_media setting.\n"
+"-    Serverlist download and server announcement.\n"
+"-    Downloads performed by main menu (e.g. mod manager).\n"
+"Only has an effect if compiled with cURL."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid fluidity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid fluidity smoothing"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid loop max"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid queue purge time"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid sinking"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid update interval in seconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Liquid update tick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Load the game profiler"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Load the game profiler to collect game profiling data.\n"
+"Provides a /profiler command to access the compiled profile.\n"
+"Useful for mod developers and server operators."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Loading Block Modifiers"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lower Y limit of dungeons."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Lower Y limit of floatlands."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Main menu script"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Make fog and sky colors depend on daytime (dawn/sunset) and view direction."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Makes all liquids opaque"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map Compression Level for Disk Storage"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map Compression Level for Network Transfer"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map directory"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map generation attributes specific to Mapgen Carpathian."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen Flat.\n"
+"Occasional lakes and hills can be added to the flat world."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen Fractal.\n"
+"'terrain' enables the generation of non-fractal terrain:\n"
+"ocean, islands and underground."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen Valleys.\n"
+"'altitude_chill': Reduces heat with altitude.\n"
+"'humid_rivers': Increases humidity around rivers.\n"
+"'vary_river_depth': If enabled, low humidity and high heat causes rivers\n"
+"to become shallower and occasionally dry.\n"
+"'altitude_dry': Reduces humidity with altitude."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map generation attributes specific to Mapgen v5."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen v6.\n"
+"The 'snowbiomes' flag enables the new 5 biome system.\n"
+"When the 'snowbiomes' flag is enabled jungles are automatically enabled and\n"
+"the 'jungles' flag is ignored."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Map generation attributes specific to Mapgen v7.\n"
+"'ridges': Rivers.\n"
+"'floatlands': Floating land masses in the atmosphere.\n"
+"'caverns': Giant caves deep underground."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map generation limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map save interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Map shadows update frames"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock limit"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock mesh generation delay"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock mesh generator's MapBlock cache size in MB"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapblock unload timeout"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Carpathian"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Carpathian specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Flat"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Flat specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Fractal"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Fractal specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V5"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V5 specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V6"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V6 specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V7"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen V7 specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Valleys"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen Valleys specific flags"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen debug"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mapgen name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max block generate distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max block send distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max liquids processed per step."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max. clearobjects extra blocks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Max. packets per iteration"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum FPS"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum FPS when the window is not focused, or when the game is paused."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum distance to render shadows."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum forceloaded blocks"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum hotbar width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum limit of random number of large caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum limit of random number of small caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum liquid resistance. Controls deceleration when entering liquid at\n"
+"high speed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of blocks that are simultaneously sent per client.\n"
+"The maximum total count is calculated dynamically:\n"
+"max_total = ceil((#clients + max_users) * per_client / 4)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of blocks that can be queued for loading."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of blocks to be queued that are to be generated.\n"
+"This limit is enforced per player."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of blocks to be queued that are to be loaded from file.\n"
+"This limit is enforced per player."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of concurrent downloads. Downloads exceeding this limit will "
+"be queued.\n"
+"This should be lower than curl_parallel_limit."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of forceloaded mapblocks."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of mapblocks for client to be kept in memory.\n"
+"Set to -1 for unlimited amount."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum number of packets sent per send step, if you have a slow connection\n"
+"try reducing it, but don't reduce it to a number below double of targeted\n"
+"client number."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of players that can be connected simultaneously."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of recent chat messages to show"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum number of statically stored objects in a block."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum objects per block"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum proportion of current window to be used for hotbar.\n"
+"Useful if there's something to be displayed right or left of hotbar."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum simultaneous block sends per client"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum size of the out chat queue"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum size of the out chat queue.\n"
+"0 to disable queueing and -1 to make the queue size unlimited."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum time a file download (e.g. a mod download) may take, stated in "
+"milliseconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Maximum time an interactive request (e.g. server list fetch) may take, "
+"stated in milliseconds."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Maximum users"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Menus"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mesh cache"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Message of the day"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Message of the day displayed to players connecting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Method used to highlight selected object."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimal level of logging to be written to chat."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimap"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimap key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimap scan height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimum limit of random number of large caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimum limit of random number of small caves per mapchunk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Minimum texture size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mipmapping"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mod channels"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Modifies the size of the HUD elements."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Monospace font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain height noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain variation noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mountain zero level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mouse sensitivity"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mouse sensitivity multiplier."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mud noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Multiplier for fall bobbing.\n"
+"For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mute key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Mute sound"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Name of map generator to be used when creating a new world.\n"
+"Creating a world in the main menu will override this.\n"
+"Current mapgens in a highly unstable state:\n"
+"-    The optional floatlands of v7 (disabled by default)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Name of the player.\n"
+"When running a server, clients connecting with this name are admins.\n"
+"When starting from the main menu, this is overridden."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Name of the server, to be displayed when players join and in the serverlist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Near plane"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Network"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Network port to listen (UDP).\n"
+"This value will be overridden when starting from the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "New users need to input this password."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Noclip"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Noclip key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Node highlighting"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "NodeTimer interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Noises"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Number of emerge threads"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Number of emerge threads to use.\n"
+"Value 0:\n"
+"-    Automatic selection. The number of emerge threads will be\n"
+"-    'number of processors - 2', with a lower limit of 1.\n"
+"Any other value:\n"
+"-    Specifies the number of emerge threads, with a lower limit of 1.\n"
+"WARNING: Increasing the number of emerge threads increases engine mapgen\n"
+"speed, but this may harm game performance by interfering with other\n"
+"processes, especially in singleplayer and/or when running Lua code in\n"
+"'on_generated'. For many users the optimum setting may be '1'."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Number of extra blocks that can be loaded by /clearobjects at once.\n"
+"This is a trade-off between SQLite transaction overhead and\n"
+"memory consumption (4096=100MB, as a rule of thumb)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Online Content Repository"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Opaque liquids"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Opaqueness (alpha) of the shadow behind the default font, between 0 and 255."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Open the pause menu when the window's focus is lost. Does not pause if a "
+"formspec is\n"
+"open."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path of the fallback font. Must be a TrueType font.\n"
+"This font will be used for certain languages or if the default font is "
+"unavailable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to save screenshots at. Can be an absolute or relative path.\n"
+"The folder will be created if it doesn't already exist."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to shader directory. If no path is defined, default location will be "
+"used."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Path to texture directory. All textures are first searched from here."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to the default font. Must be a TrueType font.\n"
+"The fallback font will be used if the font cannot be loaded."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Path to the monospace font. Must be a TrueType font.\n"
+"This font is used for e.g. the console and profiler screen."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Pause on lost window focus"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Per-player limit of queued blocks load from disk"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Per-player limit of queued blocks to generate"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Physics"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Pitch move key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Pitch move mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Place key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Place repetition interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Player is able to fly without being affected by gravity.\n"
+"This requires the \"fly\" privilege on the server."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Player name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Player transfer distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Player versus player"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Poisson filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Port to connect to (UDP).\n"
+"Note that the port field in the main menu overrides this setting."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Prevent digging and placing from repeating when holding the mouse buttons.\n"
+"Enable this when you dig or place too often by accident."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Prevent mods from doing insecure things like running shell commands."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Print the engine's profiling data in regular intervals (in seconds).\n"
+"0 = disable. Useful for developers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Privileges that players with basic_privs can grant"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Profiler"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Profiler toggle key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Profiling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Prometheus listener address"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Prometheus listener address.\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"enable metrics listener for Prometheus on that address.\n"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Proportion of large caves that contain liquid."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Radius of cloud area stated in number of 64 node cloud squares.\n"
+"Values larger than 26 will start to produce sharp cutoffs at cloud area "
+"corners."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Raises terrain to make valleys around the rivers."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Random input"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Range select key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Recent Chat Messages"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Regular font path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Remote media"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Remote port"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Remove color codes from incoming chat messages\n"
+"Use this to stop players from being able to use color in their messages"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Replaces the default main menu with a custom one."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Report path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Restricts the access of certain client-side functions on servers.\n"
+"Combine the byteflags below to restrict client-side features, or set to 0\n"
+"for no restrictions:\n"
+"LOAD_CLIENT_MODS: 1 (disable loading client-provided mods)\n"
+"CHAT_MESSAGES: 2 (disable send_chat_message call client-side)\n"
+"READ_ITEMDEFS: 4 (disable get_item_def call client-side)\n"
+"READ_NODEDEFS: 8 (disable get_node_def call client-side)\n"
+"LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to\n"
+"csm_restriction_noderange)\n"
+"READ_PLAYERINFO: 32 (disable get_player_names call client-side)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridge mountain spread noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridge noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridge underwater noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Ridged mountain size noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Right key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River channel depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River channel width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "River valley width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Rollback recording"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Rolling hill size noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Rolling hills spread noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Round minimap"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Safe digging and placing"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sandy beaches occur when np_beach exceeds this value."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Save the map received by the client on disk."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Save window size automatically when modified."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Saving map received from server"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Scale GUI by a user specified value.\n"
+"Use a nearest-neighbor-anti-alias filter to scale the GUI.\n"
+"This will smooth over some of the rough edges, and blend\n"
+"pixels when scaling down, at the cost of blurring some\n"
+"edge pixels when images are scaled by non-integer sizes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screen height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screen width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screenshot folder"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screenshot format"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Screenshot quality"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Screenshot quality. Only used for JPEG format.\n"
+"1 means worst quality; 100 means best quality.\n"
+"Use 0 for default quality."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Seabed noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Second of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Second of two 3D noises that together define tunnels."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Security"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "See https://www.sqlite.org/pragma.html#pragma_synchronous"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Selection box border color (R,G,B)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Selection box color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Selection box width"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Selects one of 18 fractal types.\n"
+"1 = 4D \"Roundy\" Mandelbrot set.\n"
+"2 = 4D \"Roundy\" Julia set.\n"
+"3 = 4D \"Squarry\" Mandelbrot set.\n"
+"4 = 4D \"Squarry\" Julia set.\n"
+"5 = 4D \"Mandy Cousin\" Mandelbrot set.\n"
+"6 = 4D \"Mandy Cousin\" Julia set.\n"
+"7 = 4D \"Variation\" Mandelbrot set.\n"
+"8 = 4D \"Variation\" Julia set.\n"
+"9 = 3D \"Mandelbrot/Mandelbar\" Mandelbrot set.\n"
+"10 = 3D \"Mandelbrot/Mandelbar\" Julia set.\n"
+"11 = 3D \"Christmas Tree\" Mandelbrot set.\n"
+"12 = 3D \"Christmas Tree\" Julia set.\n"
+"13 = 3D \"Mandelbulb\" Mandelbrot set.\n"
+"14 = 3D \"Mandelbulb\" Julia set.\n"
+"15 = 3D \"Cosine Mandelbulb\" Mandelbrot set.\n"
+"16 = 3D \"Cosine Mandelbulb\" Julia set.\n"
+"17 = 4D \"Mandelbulb\" Mandelbrot set.\n"
+"18 = 4D \"Mandelbulb\" Julia set."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server / Singleplayer"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server URL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server address"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server description"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server name"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server port"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Server side occlusion culling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Serverlist URL"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Serverlist file"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the language. Leave empty to use the system language.\n"
+"A restart is required after changing this."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Set the maximum character length of a chat message sent by clients."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the shadow strength.\n"
+"Lower value means lighter shadows, higher value means darker shadows."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the soft shadow radius size.\n"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set the tilt of Sun/Moon orbit in degrees.\n"
+"Value of 0 means no tilt / vertical orbit.\n"
+"Minimum value: 0.0; maximum value: 60.0"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable Shadow Mapping.\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable waving leaves.\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable waving liquids (like water).\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Set to true to enable waving plants.\n"
+"Requires shaders to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Sets shadow texture quality to 32 bits.\n"
+"On false, 16 bits texture will be used.\n"
+"This can cause much more artifacts in the shadow."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shader path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Shaders allow advanced visual effects and may increase performance on some "
+"video\n"
+"cards.\n"
+"This only works with the OpenGL video backend."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow filter quality"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow map max distance in nodes to render shadows"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow map texture in 32 bits"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow map texture size"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Shadow offset (in pixels) of the default font. If 0, then shadow will not be "
+"drawn."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shadow strength"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shape of the minimap. Enabled = round, disabled = square."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Show debug info"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Show entity selection boxes"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Show entity selection boxes\n"
+"A restart is required after changing this."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Show name tag backgrounds by default"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Shutdown message"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes).\n"
+"WARNING!: There is no benefit, and there are several dangers, in\n"
+"increasing this value above 5.\n"
+"Reducing this value increases cave and dungeon density.\n"
+"Altering this value is for special usage, leaving it unchanged is\n"
+"recommended."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Size of the MapBlock cache of the mesh generator. Increasing this will\n"
+"increase the cache hit %, reducing the data being copied from the main\n"
+"thread, thus reducing jitter."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sky Body Orbit Tilt"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Slice w"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Slope and fill work together to modify the heights."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small cave maximum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small cave minimum number"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small-scale humidity variation for blending biomes on borders."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Small-scale temperature variation for blending biomes on borders."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Smooth lighting"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Smooths camera when looking around. Also called look or mouse smoothing.\n"
+"Useful for recording videos."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Smooths rotation of camera in cinematic mode. 0 to disable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Smooths rotation of camera. 0 to disable."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sneak key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sneaking speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sneaking speed, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Soft shadow radius"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Sound"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Specifies URL from which client fetches media instead of using UDP.\n"
+"$filename should be accessible from $remote_media$filename via cURL\n"
+"(obviously, remote_media should end with a slash).\n"
+"Files that are not present will be fetched the usual way."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Specifies the default stack size of nodes, items and tools.\n"
+"Note that mods or games may explicitly set a stack for certain (or all) "
+"items."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread of light curve boost range.\n"
+"Controls the width of the range to be boosted.\n"
+"Standard deviation of the light curve boost Gaussian."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Static spawnpoint"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Steepness noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Step mountain size noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Step mountain spread noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Strength of 3D mode parallax."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Strength of light curve boost.\n"
+"The 3 'boost' parameters define a range of the light\n"
+"curve that is boosted in brightness."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Strict protocol checking"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Strip color codes"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Surface level of optional water placed on a solid floatland layer.\n"
+"Water is disabled by default and will only be placed if this value is set\n"
+"to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the\n"
+"upper tapering).\n"
+"***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***:\n"
+"When enabling water placement the floatlands must be configured and tested\n"
+"to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other\n"
+"required value depending on 'mgv7_np_floatland'), to avoid\n"
+"server-intensive extreme water flow and to avoid vast flooding of the\n"
+"world surface below."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Synchronous SQLite"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Temperature variation for biomes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain alternative noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain base noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain higher noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Terrain noise threshold for hills.\n"
+"Controls proportion of world area covered by hills.\n"
+"Adjust towards 0.0 for a larger proportion."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Terrain noise threshold for lakes.\n"
+"Controls proportion of world area covered by lakes.\n"
+"Adjust towards 0.0 for a larger proportion."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Terrain persistence noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Texture path"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Texture size to render the shadow map on.\n"
+"This must be a power of two.\n"
+"Bigger numbers create better shadows but it is also more expensive."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Textures on a node may be aligned either to the node or to the world.\n"
+"The former mode suits better things like machines, furniture, etc., while\n"
+"the latter makes stairs and microblocks fit surroundings better.\n"
+"However, as this possibility is new, thus may not be used by older servers,\n"
+"this option allows enforcing it for certain node types. Note though that\n"
+"that is considered EXPERIMENTAL and may not work properly."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The URL for the content repository"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The dead zone of the joystick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The default format in which profiles are being saved,\n"
+"when calling `/profiler save [format]` without format."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The depth of dirt or other biome filler node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The file path relative to your worldpath in which profiles will be saved to."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The identifier of the joystick to use"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The length in pixels it takes for touch screen interaction to start."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The maximum height of the surface of waving liquids.\n"
+"4.0 = Wave height is two nodes.\n"
+"0.0 = Wave doesn't move at all.\n"
+"Default is 1.0 (1/2 node).\n"
+"Requires waving liquids to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The network interface that the server listens on."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The privileges that new users automatically get.\n"
+"See /privs in game for a full list on your server and mod configuration."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The radius of the volume of blocks around every player that is subject to "
+"the\n"
+"active block stuff, stated in mapblocks (16 nodes).\n"
+"In active blocks objects are loaded and ABMs run.\n"
+"This is also the minimum range in which active objects (mobs) are "
+"maintained.\n"
+"This should be configured together with active_object_send_range_blocks."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The rendering back-end.\n"
+"A restart is required after changing this.\n"
+"Note: On Android, stick with OGLES1 if unsure! App may fail to start "
+"otherwise.\n"
+"On other platforms, OpenGL is recommended.\n"
+"Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The sensitivity of the joystick axes for moving the\n"
+"in-game view frustum around."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The strength (darkness) of node ambient-occlusion shading.\n"
+"Lower is darker, Higher is lighter. The valid range of values for this\n"
+"setting is 0.25 to 4.0 inclusive. If the value is out of range it will be\n"
+"set to the nearest valid value."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time (in seconds) that the liquids queue may grow beyond processing\n"
+"capacity until an attempt is made to decrease its size by dumping old queue\n"
+"items.  A value of 0 disables the functionality."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time budget allowed for ABMs to execute on each step\n"
+"(as a fraction of the ABM Interval)"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time in seconds it takes between repeated events\n"
+"when holding down a joystick button combination."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The time in seconds it takes between repeated node placements when holding\n"
+"the place button."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "The type of joystick"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"The vertical distance over which heat drops by 20 if 'altitude_chill' is\n"
+"enabled. Also the vertical distance over which humidity drops by 10 if\n"
+"'altitude_dry' is enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Third of 4 2D noises that together define hill/mountain range height."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Time in seconds for item entity (dropped items) to live.\n"
+"Setting it to -1 disables the feature."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Time of day when a new world is started, in millihours (0-23999)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Time send interval"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Time speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Timeout for client to remove unused map data from memory."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"To reduce lag, block transfers are slowed down when a player is building "
+"something.\n"
+"This determines how long they are slowed down after placing or removing a "
+"node."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Toggle camera mode key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Tooltip delay"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Touch screen threshold"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Trees noise"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Trilinear filtering"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"True = 256\n"
+"False = 128\n"
+"Usable to make minimap smoother on slower machines."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Trusted mods"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "URL to the server list displayed in the Multiplayer Tab."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Undersampling"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Undersampling is similar to using a lower screen resolution, but it applies\n"
+"to the game world only, keeping the GUI intact.\n"
+"It should give a significant performance boost at the cost of less detailed "
+"image.\n"
+"Higher values result in a less detailed image."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Unlimited player transfer distance"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Unload unused server data"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Upper Y limit of dungeons."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Upper Y limit of floatlands."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use 3D cloud look instead of flat."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use a cloud animation for the main menu background."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use anisotropic filtering when viewing at textures from an angle."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use bilinear filtering when scaling textures."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Use mipmapping to scale textures. May slightly increase performance,\n"
+"especially when using a high resolution texture pack.\n"
+"Gamma correct downscaling is not supported."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Use multi-sample antialiasing (MSAA) to smooth out block edges.\n"
+"This algorithm smooths out the 3D viewport while keeping the image sharp,\n"
+"but it doesn't affect the insides of textures\n"
+"(which is especially noticeable with transparent textures).\n"
+"Visible spaces appear between nodes when shaders are disabled.\n"
+"If set to 0, MSAA is disabled.\n"
+"A restart is required after changing this option."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Use trilinear filtering when scaling textures."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "VBO"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "VSync"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley depth"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley fill"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley profile"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Valley slope"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Variation of biome filler depth."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Variation of maximum mountain height (in nodes)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Variation of number of caves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Variation of terrain vertical scale.\n"
+"When noise is < -0.55 terrain is near-flat."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Varies depth of biome surface nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Varies roughness of terrain.\n"
+"Defines the 'persistence' value for terrain_base and terrain_alt noises."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Varies steepness of cliffs."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Vertical climbing speed, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Vertical screen synchronization."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Video driver"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View bobbing factor"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View distance in nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View range decrease key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View range increase key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "View zoom key"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Viewing range"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Virtual joystick triggers Aux1 button"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Volume"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Volume of all sounds.\n"
+"Requires the sound system to be enabled."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"W coordinate of the generated 3D slice of a 4D fractal.\n"
+"Determines which 3D slice of the 4D shape is generated.\n"
+"Alters the shape of the fractal.\n"
+"Has no effect on 3D fractals.\n"
+"Range roughly -2 to 2."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Walking and flying speed, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Walking speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Walking, flying and climbing speed in fast mode, in nodes per second."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Water level"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Water surface level of the world."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving Nodes"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving leaves"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids wave height"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids wave speed"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving liquids wavelength"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Waving plants"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Weblink color"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"When gui_scaling_filter is true, all GUI images need to be\n"
+"filtered in software, but some images are generated directly\n"
+"to hardware (e.g. render-to-texture for nodes in inventory)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"When gui_scaling_filter_txr2img is true, copy those images\n"
+"from hardware to software for scaling.  When false, fall back\n"
+"to the old scaling method, for video drivers that don't\n"
+"properly support downloading textures back from hardware."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"When using bilinear/trilinear/anisotropic filters, low-resolution textures\n"
+"can be blurred, so automatically upscale them with nearest-neighbor\n"
+"interpolation to preserve crisp pixels. This sets the minimum texture size\n"
+"for the upscaled textures; higher values look sharper, but require more\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
+"bilinear/trilinear/anisotropic filtering is enabled.\n"
+"This is also used as the base node texture size for world-aligned\n"
+"texture autoscaling."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether name tag backgrounds should be shown by default.\n"
+"Mods may still set a background."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Whether node texture animations should be desynchronized per mapblock."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether players are shown to clients without any range limit.\n"
+"Deprecated, use the setting player_transfer_distance instead."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Whether to allow players to damage and kill each other."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether to ask clients to reconnect after a (Lua) crash.\n"
+"Set this to true if your server is set up to restart automatically."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Whether to fog out the end of the visible area."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether to mute sounds. You can unmute sounds at any time, unless the\n"
+"sound system is disabled (enable_sound=false).\n"
+"In-game, you can toggle the mute state with the mute key or by using the\n"
+"pause menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Whether to show the client debug info (has the same effect as hitting F5)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Width component of the initial window size. Ignored in fullscreen mode."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Width of the selection box lines around nodes."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Windows systems only: Start Minetest with the command line window in the "
+"background.\n"
+"Contains the same information as the file debug.txt (default name)."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"World directory (everything in the world is stored here).\n"
+"Not needed if starting from the main menu."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "World start time"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"World-aligned textures may be scaled to span several nodes. However,\n"
+"the server may not send the scale you want, especially if you use\n"
+"a specially-designed texture pack; with this option, the client tries\n"
+"to determine the scale automatically basing on the texture size.\n"
+"See also texture_min_size.\n"
+"Warning: This option is EXPERIMENTAL!"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "World-aligned textures mode"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y of flat ground."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Y of mountain density gradient zero level. Used to shift mountains "
+"vertically."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y of upper limit of large caves."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-distance over which caverns expand to full size."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Y-distance over which floatlands taper from full density to nothing.\n"
+"Tapering starts at this distance from the Y limit.\n"
+"For a solid floatland layer, this controls the height of hills/mountains.\n"
+"Must be less than or equal to half the distance between the Y limits."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of average terrain surface."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of cavern upper limit."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of higher terrain that creates cliffs."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of lower terrain and seabed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Y-level of seabed."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "cURL file download timeout"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "cURL interactive timeout"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "cURL parallel limit"
+msgstr ""
index 2aa7edeb4b8890706a716aa7c23140d74ace41ed..1b9e17f8ec4c4a9044d548afd3c124947d3a51fc 100644 (file)
@@ -2,9 +2,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Chinese (Simplified) (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-06-10 14:35+0000\n"
-"Last-Translator: Riceball LEE <snowyu.lee@gmail.com>\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-30 18:51+0000\n"
+"Last-Translator: poi <erbaotao@outlook.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "minetest/minetest/zh_Hans/>\n"
 "Language: zh_CN\n"
@@ -12,49 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.11-dev\n"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Clear the out chat queue"
-msgstr "æ\98¾ç¤ºæ\9c\80大è\81\8a天记å½\95ç\9a\84è¡\8c度"
+msgstr "æ¸\85é\99¤è\81\8a天å\8f\91é\80\81é\98\9få\88\97"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "聊天命令"
+msgstr "空命令。"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "退出至菜单"
+msgstr "退出至菜单"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "æ\9c¬å\9c°å\91½ä»¤"
+msgstr "æ\97 æ\95\88å\91½ä»¤ "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "发送的命令 "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "å\8d\95人游æ\88\8f"
+msgstr "å\88\97å\87ºè\81\94æ\9cºç\8e©å®¶"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "å\8d\95人游æ\88\8f"
+msgstr "å\9c¨çº¿ç\8e©å®¶: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "聊天发送队列现在为空。"
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "服务器已禁用该命令."
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -64,42 +58,41 @@ msgstr "重生"
 msgid "You died"
 msgstr "您已经死亡"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "您已经死亡"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "本地命令"
+msgstr "可用命令:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "本地命令"
+msgstr "可用命令: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "命令不可用: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "获取命令帮助"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
 msgstr ""
+"使用 '.help <cmd>' 获取该命令的更多信息,或使用 '.help all' 列出所有内容。"
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <命令>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+#, fuzzy
+msgid "<none available>"
+msgstr "命令不可用:"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua 脚本发生错误:"
@@ -110,7 +103,7 @@ msgstr "发生了错误:"
 
 #: builtin/fstk/ui.lua
 msgid "Main menu"
-msgstr "主单"
+msgstr "主单"
 
 #: builtin/fstk/ui.lua
 msgid "Reconnect"
@@ -233,7 +226,7 @@ msgstr "$1 和 $2 依赖项将被安装."
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 by $2"
-msgstr ""
+msgstr "$1  作者: $2"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid ""
@@ -249,7 +242,7 @@ msgstr "正在下载 $1 ……"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 required dependencies could not be found."
-msgstr "没æ\9c\89æ\89¾å\88°é\9c\80è¦\81ç\9a\84ä¾\9dèµ\96项: $1"
+msgstr "æ\9c\89$1个ä¾\9dèµ\96项没æ\9c\89æ\89¾å\88°ã\80\82"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "$1 will be installed, and $2 dependencies will be skipped."
@@ -300,6 +293,11 @@ msgstr "安装$1"
 msgid "Install missing dependencies"
 msgstr "安装缺失的依赖项"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+#, fuzzy
+msgid "Install: Unsupported file type or broken archive"
+msgstr "安装:文件类型不支持或档案已损坏"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -330,7 +328,6 @@ msgid "Please check that the base game is correct."
 msgstr "请查看游戏是否正确。"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Queued"
 msgstr "已加入队列"
 
@@ -523,7 +520,7 @@ msgstr "温带,沙漠,丛林,苔原,泰加林带"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Terrain surface erosion"
-msgstr "地形表面腐烂"
+msgstr "地形表面侵蚀"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
@@ -627,7 +624,8 @@ msgid "Offset"
 msgstr "补偿"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-msgid "Persistance"
+#, fuzzy
+msgid "Persistence"
 msgstr "持续性"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
@@ -737,14 +735,6 @@ msgstr "安装mod:无法找到$1的真实mod名称"
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "安装mod:无法找到mod包$1的合适文件夹名"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "安装:“$1“为不支持的文件类型或已损坏"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "安装:文件:”$1“"
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "无法找到mod或mod包"
@@ -779,16 +769,15 @@ msgstr "请尝试重新启用公共服务器列表并检查您的网络连接。
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "关于"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
 msgstr "积极贡献者"
 
 #: builtin/mainmenu/tab_about.lua
-#, fuzzy
 msgid "Active renderer:"
-msgstr "活动目标发送范围"
+msgstr "主动渲染器:"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Core Developers"
@@ -803,6 +792,8 @@ msgid ""
 "Opens the directory that contains user-provided worlds, games, mods,\n"
 "and texture packs in a file manager / explorer."
 msgstr ""
+"在文件(资源)管理器中打开含有用户提供的世界,游戏,mods\n"
+"和纹理包的目录。"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Previous Contributors"
@@ -921,9 +912,8 @@ msgid "Start Game"
 msgstr "启动游戏"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- 地址: "
+msgstr "地址"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -939,22 +929,20 @@ msgstr "创造模式"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "伤害"
+msgstr "伤害 / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "删除收藏项"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
-msgstr "æ\94¶è\97\8f项"
+msgstr "æ\88\91ç\9a\84æ\94¶è\97\8f"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "不兼容的服务器"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -965,16 +953,14 @@ msgid "Ping"
 msgstr "应答速度"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
 msgstr "公开服务器"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "刷新"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "服务器描述"
 
@@ -1019,13 +1005,12 @@ msgid "Connected Glass"
 msgstr "连通玻璃"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "å­\97ä½\93阴影"
+msgstr "å\8a¨æ\80\81阴影"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "动态阴影: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1033,15 +1018,15 @@ msgstr "华丽树叶"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Mipmap"
@@ -1115,10 +1100,6 @@ msgstr "平滑光照"
 msgid "Texturing:"
 msgstr "材质:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "启用着色器需要使用OpenGL驱动。"
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "色调映射"
@@ -1133,11 +1114,11 @@ msgstr "三线性过滤"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "超出高度限制"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "过于低"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1151,7 +1132,7 @@ msgstr "摇动流体"
 msgid "Waving Plants"
 msgstr "摇摆植物"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "连接超时。"
 
@@ -1180,8 +1161,8 @@ msgid "Connection error (timed out?)"
 msgstr "连接出错(超时?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "æ\97 æ³\95æ\89¾å\88°æ\88\96è\80\85è½½å\85¥æ¸¸æ\88\8f \""
+msgid "Could not find or load game"
+msgstr "æ\89¾ä¸\8då\88°å­\90游æ\88\8fæ\88\96è\80\85æ\97 æ³\95è½½å\85¥å­\90游æ\88\8fï¼\9a "
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1223,14 +1204,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- 地址: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- 创造模式: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- 伤害: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- 模式: "
@@ -1252,6 +1225,15 @@ msgstr "- 玩家对战: "
 msgid "- Server Name: "
 msgstr "- 服务器名称: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "序列化发生了错误:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "访问被拒绝。原因:%s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "自动前进已禁用"
@@ -1260,6 +1242,23 @@ msgstr "自动前进已禁用"
 msgid "Automatic forward enabled"
 msgstr "自动前进已启用"
 
+#: src/client/game.cpp
+#, fuzzy
+msgid "Block bounds hidden"
+msgstr "地图块边界"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr ""
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "已禁用镜头更新"
@@ -1268,6 +1267,10 @@ msgstr "已禁用镜头更新"
 msgid "Camera update enabled"
 msgstr "已启用镜头更新"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr ""
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "更改密码"
@@ -1280,6 +1283,10 @@ msgstr "电影模式已禁用"
 msgid "Cinematic mode enabled"
 msgstr "电影模式已启用"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "与客户端的连接已断开"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "客户端脚本已禁用"
@@ -1288,12 +1295,16 @@ msgstr "客户端脚本已禁用"
 msgid "Connecting to server..."
 msgstr "正在连接服务器..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "连接失败,原因不明"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "继续"
 
 #: src/client/game.cpp
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "Controls:\n"
 "- %s: move forwards\n"
@@ -1315,16 +1326,21 @@ msgstr ""
 "- %s:向后移动\n"
 "- %s:向左移动\n"
 "- %s:向右移动\n"
-"- %s:跳/爬\n"
-"- %s:潜行/向下\n"
+"- %s:跳/向上(攀爬)\n"
+"- %s:挖/打\n"
+"- %s:放/使用\n"
+"- %s:潜行/向下(攀爬)\n"
 "- %s:丢弃物品\n"
 "- %s:物品清单\n"
 "- 鼠标:转身/环顾\n"
-"- 鼠标左键: 挖/打\n"
-"- 鼠标右键: 放/使用\n"
 "- 鼠标滚轮: 选择物品\n"
 "- %s:聊天\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "地址无法解析:%s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "正在建立客户端..."
@@ -1454,9 +1470,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "小地图被当前子游戏或者 mod 禁用"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "å\8d\95人游戏"
+msgstr "å¤\9a人游戏"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1530,6 +1545,21 @@ msgstr "此编译版本不支持声音系统"
 msgid "Sound unmuted"
 msgstr "已取消静音"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "此服务器运行的可能是别的版本,%s。"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "无法连接到 %s,因为 IPv6 已禁用"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "无法监听 %s,因为 IPv6 已禁用"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1851,19 +1881,27 @@ msgid "Minimap hidden"
 msgstr "小地图已隐藏"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in radar mode, Zoom x%d"
-msgstr "雷达小地图,放大至倍"
+msgstr "雷达小地图,放大至%d倍"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in surface mode, Zoom x%d"
-msgstr "地表模式小地图, 放大至倍"
+msgstr "地表模式小地图, 放大至%d倍"
 
 #: src/client/minimap.cpp
 msgid "Minimap in texture mode"
 msgstr "材质模式小地图"
 
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "网页打不开"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "正在打开网页"
+
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
 msgstr "密码不匹配!"
@@ -1890,9 +1928,8 @@ msgid "Proceed"
 msgstr "继续"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "“特殊” = 向下爬"
+msgstr "“Aux1” = 向下爬"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1904,7 +1941,7 @@ msgstr "自动跳跃"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1912,7 +1949,7 @@ msgstr "向后"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "地图块边界"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2063,8 +2100,9 @@ msgid "Muted"
 msgstr "静音"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "音量: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "音量:%d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2088,14 +2126,13 @@ msgstr ""
 "如果禁用,虚拟操纵杆将居中至第一次触摸的位置。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
 msgstr ""
-"(安卓)使用虚拟操纵杆触发\"aux\"按钮。\n"
-"如果启用,虚拟操纵杆在主圆圈外会点击\"aux\"按钮。"
+"(安卓)使用虚拟操纵杆触发\"Aux1\"按钮。\n"
+"如果启用,虚拟操纵杆在主圆圈外会点击\"Aux1\"按钮。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2311,6 +2348,11 @@ msgid ""
 "screens."
 msgstr "为支持4K等屏幕,调节像素点密度(非 X11/Android 环境才有效)。"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr "调整检测到的显示密度,用来缩放 UI 元素。"
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2321,10 +2363,10 @@ msgid ""
 "to be sure) creates a solid floatland layer."
 msgstr ""
 "调整悬空岛层的密度。\n"
-"增加值增加密度。可以是正值或负值。\n"
-"值等于0.0, 容积的50%是floatland。\n"
-"值等于2.0  ,(可以更高,取决于 'mgv7_np_floatland' ,始终测试以确定)\n"
-"å\88\9b建ä¸\80个å\9d\9a实的悬空岛层。"
+"增加值,就增加密度。可以是正值或负值。\n"
+"值等于 0.0, 容积的 50% 是悬空岛。\n"
+"值等于 2.0,(值可以更高,取决于“mgv7_np_floatland”,但一定要测试确定)\n"
+"å\88\9b建ä¸\80个å¯\86实的悬空岛层。"
 
 #: src/settings_translation_file.cpp
 msgid "Advanced"
@@ -2444,14 +2486,12 @@ msgid "Autoscaling mode"
 msgstr "自动缩放模式"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "跳跃键"
+msgstr "Aux1键"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "用于攀登/降落的特殊键"
+msgstr "用于攀登/降落的Aux1键"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
@@ -2519,7 +2559,7 @@ msgstr "粗体等宽字体路径"
 
 #: src/settings_translation_file.cpp
 msgid "Build inside player"
-msgstr "在玩家内部搭建"
+msgstr "在玩家站着的地方搭建"
 
 #: src/settings_translation_file.cpp
 msgid "Builtin"
@@ -2602,9 +2642,12 @@ msgstr ""
 "0.0为最小值时1.0为最大值。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat command time message threshold"
-msgstr "聊天消息踢出阈值"
+msgstr "显示聊天消息执行时间的阀值(秒)"
+
+#: src/settings_translation_file.cpp
+msgid "Chat commands"
+msgstr "聊天指令"
 
 #: src/settings_translation_file.cpp
 msgid "Chat font size"
@@ -2639,8 +2682,8 @@ msgid "Chat toggle key"
 msgstr "聊天启用/禁用键"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "聊天命令"
+msgid "Chat weblinks"
+msgstr "聊天网页链接"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2658,6 +2701,13 @@ msgstr "电影模式键"
 msgid "Clean transparent textures"
 msgstr "干净透明材质"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr ""
+"在聊天控制台输出中启用了可点击的网页链接(中键单击或 Ctrl + 左键单击)。"
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "客户端"
@@ -2703,9 +2753,8 @@ msgid "Colored fog"
 msgstr "彩色雾"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "彩è\89²é\9b¾"
+msgstr "彩è\89²é\98´å½±"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2744,6 +2793,22 @@ msgstr ""
 msgid "Command key"
 msgstr "命令键"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "连接玻璃"
@@ -2844,8 +2909,10 @@ msgstr "准星透明"
 #, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
-msgstr "准星不透明度(0-255)。"
+"This also applies to the object crosshair."
+msgstr ""
+"准星不透明度(0-255)。\n"
+"实体准星的不透明度也会使用此值。"
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2856,6 +2923,8 @@ msgid ""
 "Crosshair color (R,G,B).\n"
 "Also controls the object crosshair color"
 msgstr ""
+"准星颜色(R,G,B).\n"
+"还控制对象准星颜色"
 
 #: src/settings_translation_file.cpp
 msgid "DPI"
@@ -2923,10 +2992,13 @@ msgstr "默认栈大小"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
+"设定阴影滤镜的质量。\n"
+"使用 PCF 或 泊松盘(Poisson disk)算法模拟软阴影效果\n"
+"但也会使用更多的硬件资源。"
 
 #: src/settings_translation_file.cpp
 msgid "Defines areas where trees have apples."
@@ -3031,9 +3103,8 @@ msgid "Desynchronize block animation"
 msgstr "去同步块动画"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dig key"
-msgstr "右方向键"
+msgstr "挖掘键"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3047,6 +3118,10 @@ msgstr "禁用反作弊"
 msgid "Disallow empty passwords"
 msgstr "禁止使用空密码"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "显示密度比例系数"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "服务器域名,将显示在服务器列表。"
@@ -3097,9 +3172,21 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+"启用泊松盘(Poisson disk)滤镜。\n"
+"使用泊松盘算法来产生“软阴影”。不启用的话就会使用 PCF 滤镜。"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
+"启用彩色阴影。\n"
+"在半透明节点上投射彩色阴影。会消耗超多的资源。"
 
 #: src/settings_translation_file.cpp
 msgid "Enable console window"
@@ -3125,13 +3212,6 @@ msgstr "启用 mod 安全"
 msgid "Enable players getting damage and dying."
 msgstr "启用玩家受到伤害和死亡。"
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "启用随机用户输入(仅用于测试)。"
@@ -3241,6 +3321,12 @@ msgstr ""
 "游戏内声音控制将失效。\n"
 "改变此设置需要重启。"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr "允许不影响可玩性的轻微视觉错误,以此减少 CPU 负载,或提高渲染性能。"
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "打印引擎性能分析数据间隔"
@@ -3301,12 +3387,11 @@ msgid "Fast movement"
 msgstr "快速移动"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Fast movement (via the \"Aux1\" key).\n"
 "This requires the \"fast\" privilege on the server."
 msgstr ""
-"快速移动(通过“特殊”键)。\n"
+"快速移动(通过“Aux1”键)。\n"
 "这需要服务器的“fast”权限。"
 
 #: src/settings_translation_file.cpp
@@ -3339,7 +3424,6 @@ msgid "Filmic tone mapping"
 msgstr "电影色调映射"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Filtered textures can blend RGB values with fully-transparent neighbors,\n"
 "which PNG optimizers usually discard, often resulting in dark or\n"
@@ -3348,8 +3432,8 @@ msgid ""
 msgstr ""
 "经过滤的材质会与邻近的全透明材质混合RGB值,\n"
 "该值通常会被PNG优化器丢弃,某些时候会给透明材质产生暗色或\n"
-"亮色的边缘。应用该过滤器将在材质加载时\n"
-"移除该效果。"
+"亮色的边缘。应用该过滤器将在材质加载时移除该效果。\n"
+"该过滤器将在启用mipmapping的时候被自动应用。"
 
 #: src/settings_translation_file.cpp
 msgid "Filtering"
@@ -3440,11 +3524,17 @@ msgid "Font size"
 msgstr "字体大小"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
 msgstr "默认字体大小,单位pt。"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+#, fuzzy
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr "等宽字体大小,单位pt。"
 
 #: src/settings_translation_file.cpp
@@ -3455,6 +3545,17 @@ msgstr ""
 "最近聊天文本和聊天提示的字体大小(pt)。\n"
 "值为0将使用默认字体大小。"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3516,10 +3617,6 @@ msgstr "分形类型"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "从雾起始点开始雾的可见距离分数"
 
-#: src/settings_translation_file.cpp
-msgid "FreeType fonts"
-msgstr "FreeType 字体"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3570,10 +3667,11 @@ msgid "Global callbacks"
 msgstr "全局回调"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "全局地图生成属性。\n"
 "在地图生成器 v6 中‘decorations’标签控制除树木和丛林草外所有装饰物。\n"
@@ -3624,7 +3722,6 @@ msgid "HUD toggle key"
 msgstr "HUD启用/禁用键"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Handling for deprecated Lua API calls:\n"
 "-    none: Do not log deprecated calls\n"
@@ -3632,9 +3729,9 @@ msgid ""
 "-    error: abort on usage of deprecated call (suggested for mod developers)."
 msgstr ""
 "处理已弃用的 Lua API 调用:\n"
-"-    兼容:(尝试)模拟旧的调用(发布版本的默认值)。\n"
-"-    记录:模拟并记录已弃用的调用的回溯(调试的默认值)。\n"
-"-    错误:停止使用已弃用的调用(Mod 开发人员推荐)。"
+"-    none:不记录废弃的调用。\n"
+"-    log:模拟并记录已弃用的调用的回溯(调试的默认值)。\n"
+"-    error:停止使用已弃用的调用(Mod 开发人员推荐)。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3658,10 +3755,9 @@ msgid "Heat noise"
 msgstr "热噪声"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Height component of the initial window size. Ignored in fullscreen mode."
-msgstr "初始窗口高度。"
+msgstr "初始窗口高度,全屏模式下忽略该值。"
 
 #: src/settings_translation_file.cpp
 msgid "Height noise"
@@ -3914,13 +4010,10 @@ msgstr ""
 "节省无效 CPU 功耗。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If disabled, \"Aux1\" key is used to fly fast if both fly and fast mode are\n"
 "enabled."
-msgstr ""
-"如果禁用,当飞行和快速模式同时启用时“特殊”键用于快速\n"
-"飞行。"
+msgstr "如果禁用,“Aux1”键将用于快速飞行(飞行和快速模式同时启用)。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3945,13 +4038,12 @@ msgstr ""
 "这需要服务器的“noclip”权限。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "If enabled, \"Aux1\" key instead of \"Sneak\" key is used for climbing down "
 "and\n"
 "descending."
 msgstr ""
-"如果启用,“特殊”键将代替潜行键的向下攀爬和\n"
+"如果启用,“Aux1”键将代替潜行键的向下攀爬和\n"
 "下降。"
 
 #: src/settings_translation_file.cpp
@@ -4000,13 +4092,15 @@ msgid ""
 "to this distance from the player to the node."
 msgstr ""
 "如果客户端mod方块范围限制启用,限制get_node至玩家\n"
-"到方块的距离"
+"到方块的距离"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "If the execution of a chat command takes longer than this specified time in\n"
 "seconds, add the time information to the chat command message"
 msgstr ""
+"如果聊天命令的执行时间长于此指定以秒为单位时间,请将时间信息添加到聊天命令消"
+"息中。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -4061,7 +4155,8 @@ msgstr ""
 "通常只有核心/内部构建者需要"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "登录时的聊天命令。"
 
 #: src/settings_translation_file.cpp
@@ -4151,7 +4246,8 @@ msgid "Joystick button repetition interval"
 msgstr "摇杆按钮重复间隔"
 
 #: src/settings_translation_file.cpp
-msgid "Joystick deadzone"
+#, fuzzy
+msgid "Joystick dead zone"
 msgstr "摇杆无效区"
 
 #: src/settings_translation_file.cpp
@@ -5261,7 +5357,7 @@ msgstr "地图保存间隔"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "液体更新时钟间隔"
 
 #: src/settings_translation_file.cpp
@@ -5374,7 +5470,7 @@ msgstr "窗口未聚焦或游戏暂停时的最大 FPS。"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum distance to render shadows."
-msgstr ""
+msgstr "最大渲染阴影距离。"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum forceloaded blocks"
@@ -5436,6 +5532,8 @@ msgid ""
 "be queued.\n"
 "This should be lower than curl_parallel_limit."
 msgstr ""
+"最大并发下载数。 超过此限制的下载将排队。 这应该低于 curl_parallel_limit(卷"
+"曲平行限制)。"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum number of forceloaded mapblocks."
@@ -5510,7 +5608,7 @@ msgstr "单个文件下载(如mod下载)的最大时间。"
 msgid ""
 "Maximum time an interactive request (e.g. server list fetch) may take, "
 "stated in milliseconds."
-msgstr ""
+msgstr "交互式请求(例如服务器列表获取)可能需要的最长时间,以毫秒为单位。"
 
 #: src/settings_translation_file.cpp
 msgid "Maximum users"
@@ -5573,7 +5671,8 @@ msgid "Mod channels"
 msgstr "mod频道"
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "更改hud栏元素大小。"
 
 #: src/settings_translation_file.cpp
@@ -5584,6 +5683,11 @@ msgstr "等宽字体路径"
 msgid "Monospace font size"
 msgstr "等宽字体大小"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "等宽字体大小"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "山高度噪声"
@@ -5724,9 +5828,10 @@ msgstr ""
 "佳值为'1'。"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "/clearobjects每次能加载的额外方块数。\n"
@@ -5756,10 +5861,13 @@ msgstr ""
 "则不暂停。"
 
 #: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr "替换聊天网页链接的颜色,可用可不用。"
+
+#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5787,10 +5895,9 @@ msgid "Path to texture directory. All textures are first searched from here."
 msgstr "材质目录路径。所有材质都首先从此路径搜索。"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 "默认字体路径。\n"
@@ -5799,10 +5906,9 @@ msgstr ""
 "后备字体用于不可用默认字体的语言。"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 "等宽字体路径。\n"
@@ -5917,11 +6023,12 @@ msgid "Prometheus listener address"
 msgstr "Prometheus 监听器地址"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 "Prometheus 监听器地址。\n"
 "如果minetest是在启用ENABLE_PROMETHEUS选项的情况下编译的,\n"
@@ -6260,28 +6367,30 @@ msgid ""
 "Set the shadow strength.\n"
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
+"设置阴影强度。\n"
+"较低的值表示较亮的阴影,较高的值表示较暗的阴影。"
 
 #: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
-#: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
+"设置软阴影半径大小。\n"
+"较低的值意味着更清晰的阴影更大的值更柔和。\n"
+"最小值 1.0 和最大值 10.0"
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
+"以度为单位设置太阳/月亮轨道的倾斜度\n"
+"值 0 表示没有倾斜/垂直轨道。\n"
+"最小值 0.0 和最大值 60.0"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -6322,6 +6431,9 @@ msgid ""
 "On false, 16 bits texture will be used.\n"
 "This can cause much more artifacts in the shadow."
 msgstr ""
+"将阴影纹理质量设置为 32 位。\n"
+"如果为 false(否),将使用 16 位纹理。\n"
+"这可能会导致阴影中出现更多阴影。"
 
 #: src/settings_translation_file.cpp
 msgid "Shader path"
@@ -6345,11 +6457,11 @@ msgstr "截图品质"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map max distance in nodes to render shadows"
-msgstr ""
+msgstr "渲染阴影的节点中的阴影贴图最大距离"
 
 #: src/settings_translation_file.cpp
 msgid "Shadow map texture in 32 bits"
-msgstr ""
+msgstr "32 位阴影贴图纹理"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -6364,7 +6476,7 @@ msgstr "默认字体阴影偏移(单位为像素),0 表示不绘制阴影
 
 #: src/settings_translation_file.cpp
 msgid "Shadow strength"
-msgstr ""
+msgstr "阴影强度"
 
 #: src/settings_translation_file.cpp
 msgid "Shape of the minimap. Enabled = round, disabled = square."
@@ -6388,7 +6500,8 @@ msgstr ""
 "变更后须重新启动。"
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+#, fuzzy
+msgid "Show name tag backgrounds by default"
 msgstr "默认显示名称标签背景"
 
 #: src/settings_translation_file.cpp
@@ -6423,7 +6536,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid "Sky Body Orbit Tilt"
-msgstr ""
+msgstr "天体轨道倾斜"
 
 #: src/settings_translation_file.cpp
 msgid "Slice w"
@@ -6511,6 +6624,18 @@ msgstr ""
 "指定节点、物品和工具的默认堆叠数量。\n"
 "请注意,mod或游戏可能会为某些(或所有)项目明确设置堆栈。"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+"把完整地更新一次阴影贴图这项任务分配给多少帧去完成。\n"
+"较高的值可能会使阴影滞后,较低的值\n"
+"将消耗更多硬件资源。\n"
+"最小值:1;最大值:16"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6643,8 +6768,11 @@ msgstr "材质路径"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
+"用于渲染阴影贴图的材质尺寸。\n"
+"数值必须是 2 的幂。\n"
+"数值更大,阴影更好,但运算也更加复杂。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6661,7 +6789,8 @@ msgid "The URL for the content repository"
 msgstr "内容存储库的 URL"
 
 #: src/settings_translation_file.cpp
-msgid "The deadzone of the joystick"
+#, fuzzy
+msgid "The dead zone of the joystick"
 msgstr "摇杆的无效区"
 
 #: src/settings_translation_file.cpp
@@ -6671,8 +6800,9 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid "The depth of dirt or other biome filler node."
-msgstr "泥土深度或其他生物群系过滤节点"
+msgstr "泥土深度或其他生物群系过滤节点"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6732,8 +6862,10 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
+"摇杆轴灵敏度(用于移动子游戏中棱台体形状的\n"
+"可见区域的摇杆轴)。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -6831,6 +6963,10 @@ msgstr "工具提示延迟"
 msgid "Touch screen threshold"
 msgstr "触屏阈值"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr "性能权衡"
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "树木噪声"
@@ -6904,7 +7040,7 @@ msgstr "缩放材质时使用双线过滤。"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7093,6 +7229,11 @@ msgstr "波动液体波动长度"
 msgid "Waving plants"
 msgstr "摇动植物"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "选择框颜色"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7114,7 +7255,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7122,14 +7263,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7262,24 +7396,6 @@ msgstr "较低地形与海底的Y坐标。"
 msgid "Y-level of seabed."
 msgstr "海底的Y坐标。"
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL 文件下载超时"
@@ -7293,6 +7409,12 @@ msgstr "cURL 超时"
 msgid "cURL parallel limit"
 msgstr "cURL 并发限制"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- 创造模式: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- 伤害: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7448,6 +7570,9 @@ msgstr "cURL 并发限制"
 #~ msgid "Font size of the fallback font in point (pt)."
 #~ msgstr "后备字体大小,单位pt。"
 
+#~ msgid "FreeType fonts"
+#~ msgstr "FreeType 字体"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "全屏 BPP"
 
@@ -7466,6 +7591,9 @@ msgstr "cURL 并发限制"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 支持。"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "安装:文件:”$1“"
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "巨大洞穴深度"
@@ -7562,6 +7690,16 @@ msgstr "cURL 并发限制"
 #~ msgid "Select Package File:"
 #~ msgstr "选择包文件:"
 
+#~ msgid ""
+#~ "Set the shadow update time.\n"
+#~ "Lower value means shadows and map updates faster, but it consume more "
+#~ "resources.\n"
+#~ "Minimun value 0.001 seconds max value 0.2 seconds"
+#~ msgstr ""
+#~ "设置阴影更新时间。\n"
+#~ "较低的值意味着阴影和贴图更新更快,但会消耗更多资源。\n"
+#~ "最小值 0.001 秒 最大值 0.2 秒"
+
 #, fuzzy
 #~ msgid "Shadow limit"
 #~ msgstr "地图块限制"
@@ -7586,6 +7724,9 @@ msgstr "cURL 并发限制"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "用于特定语言的字体。"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "启用着色器需要使用OpenGL驱动。"
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "切换电影模式"
 
@@ -7605,5 +7746,8 @@ msgstr "cURL 并发限制"
 #~ msgid "Yes"
 #~ msgstr "是"
 
+#~ msgid "You died."
+#~ msgstr "您已经死亡."
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index 8d6d22ae3b180a823d9f625202d87be7cf7bb6e6..ae10a17ffc68913d7fc31c37f8cceafdd7c288a2 100644 (file)
@@ -2,8 +2,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Chinese (Traditional) (Minetest)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-06-16 18:27+0200\n"
-"PO-Revision-Date: 2021-05-20 14:34+0000\n"
+"POT-Creation-Date: 2022-01-25 23:19+0100\n"
+"PO-Revision-Date: 2022-01-16 02:52+0000\n"
 "Last-Translator: Yiu Man Ho <yiufamily.hh@gmail.com>\n"
 "Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
 "minetest/minetest/zh_Hant/>\n"
@@ -12,48 +12,43 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 4.10.1\n"
 
 #: builtin/client/chatcommands.lua
 msgid "Clear the out chat queue"
-msgstr ""
+msgstr "清除聊天佇列"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Empty command."
-msgstr "聊天指令"
+msgstr "清空指令。"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Exit to main menu"
-msgstr "離開回到選單"
+msgstr "離開回到選單"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Invalid command: "
-msgstr "本機指令"
+msgstr "無效的指令: "
 
 #: builtin/client/chatcommands.lua
 msgid "Issued command: "
-msgstr ""
+msgstr "發送的指令: "
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "List online players"
-msgstr "å\96®äººé\81\8aæ\88²"
+msgstr "å\88\97å\87ºç·\9aä¸\8aç\8e©å®¶"
 
 #: builtin/client/chatcommands.lua
-#, fuzzy
 msgid "Online players: "
-msgstr "單人遊戲"
+msgstr "線上玩家: "
 
 #: builtin/client/chatcommands.lua
 msgid "The out chat queue is now empty."
-msgstr ""
+msgstr "對外聊天佇列現在為空。"
 
 #: builtin/client/chatcommands.lua
 msgid "This command is disabled by server."
-msgstr ""
+msgstr "這個指令被伺服器停用。"
 
 #: builtin/client/death_formspec.lua src/client/game.cpp
 msgid "Respawn"
@@ -63,42 +58,39 @@ msgstr "重生"
 msgid "You died"
 msgstr "您已死亡"
 
-#: builtin/client/death_formspec.lua
-#, fuzzy
-msgid "You died."
-msgstr "您已死亡"
-
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands:"
-msgstr "本機指令"
+msgstr "可用的指令:"
 
 #: builtin/common/chatcommands.lua
-#, fuzzy
 msgid "Available commands: "
-msgstr "本機指令"
+msgstr "可用的指令: "
 
 #: builtin/common/chatcommands.lua
 msgid "Command not available: "
-msgstr ""
+msgstr "指令無法使用: "
 
 #: builtin/common/chatcommands.lua
 msgid "Get help for commands"
-msgstr ""
+msgstr "取得指令的說明"
 
 #: builtin/common/chatcommands.lua
 msgid ""
 "Use '.help <cmd>' to get more information, or '.help all' to list everything."
-msgstr ""
+msgstr "使用「.help <cmd>」來取得更多資訊,或使用「.help all」來列出所有指令。"
 
 #: builtin/common/chatcommands.lua
 msgid "[all | <cmd>]"
-msgstr ""
+msgstr "[all | <cmd>]"
 
 #: builtin/fstk/dialog.lua builtin/fstk/ui.lua src/gui/modalMenu.cpp
 msgid "OK"
 msgstr "OK"
 
+#: builtin/fstk/ui.lua
+msgid "<none available>"
+msgstr "<沒有可用的>"
+
 #: builtin/fstk/ui.lua
 msgid "An error occurred in a Lua script:"
 msgstr "Lua 指令稿發生錯誤:"
@@ -259,23 +251,20 @@ msgid "All packages"
 msgstr "所有套件"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Already installed"
-msgstr "已使用此按鍵"
+msgstr "已安裝"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Back to Main Menu"
 msgstr "返回主選單"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "Base Game:"
-msgstr "主持遊戲"
+msgstr "主遊戲:"
 
 #: builtin/mainmenu/dlg_contentstore.lua
-#, fuzzy
 msgid "ContentDB is not available when Minetest was compiled without cURL"
-msgstr "在沒有cURL的情況下編譯Minetest時,ContentDB不可用"
+msgstr "在沒有 cURL 的情況下編譯 Minetest 時,ContentDB 不可用"
 
 #: builtin/mainmenu/dlg_contentstore.lua
 msgid "Downloading..."
@@ -302,6 +291,10 @@ msgstr "安裝 $1"
 msgid "Install missing dependencies"
 msgstr "安裝缺少的依賴"
 
+#: builtin/mainmenu/dlg_contentstore.lua
+msgid "Install: Unsupported file type or broken archive"
+msgstr "安裝:檔案類型不支援,或是封存檔損壞"
+
 #: builtin/mainmenu/dlg_contentstore.lua
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Mods"
@@ -436,12 +429,10 @@ msgid "Hills"
 msgstr "山"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Humid rivers"
-msgstr "顯示卡驅動程式"
+msgstr "潮濕的河流"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Increases humidity around rivers"
 msgstr "增加河流周圍的濕度"
 
@@ -450,9 +441,8 @@ msgid "Lakes"
 msgstr "河流"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Low humidity and high heat causes shallow or dry rivers"
-msgstr "因低濕度和高熱而導致河流淺或乾燥"
+msgstr "因低濕度和高熱而導致河流淺或乾燥"
 
 #: builtin/mainmenu/dlg_create_world.lua src/settings_translation_file.cpp
 msgid "Mapgen"
@@ -475,7 +465,6 @@ msgid "Mud flow"
 msgstr "泥石流"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Network of tunnels and caves"
 msgstr "隧道和洞穴網絡"
 
@@ -485,11 +474,11 @@ msgstr "未選擇遊戲"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces heat with altitude"
-msgstr ""
+msgstr "隨海拔降低熱度"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Reduces humidity with altitude"
-msgstr ""
+msgstr "濕度隨海拔升高而降低"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Rivers"
@@ -519,31 +508,28 @@ msgid "Structures appearing on the terrain, typically trees and plants"
 msgstr "出現在世界上的結構,通常是樹木和植物"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Temperate, Desert"
 msgstr "溫帶沙漠"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle"
-msgstr ""
+msgstr "溫帶、沙漠、叢林"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Temperate, Desert, Jungle, Tundra, Taiga"
-msgstr ""
+msgstr "溫帶,沙漠,叢林,苔原,針葉林"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Terrain surface erosion"
-msgstr "地形基礎高度"
+msgstr "地形表面侵蝕"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Trees and jungle grass"
 msgstr "樹木和叢林草"
 
 #: builtin/mainmenu/dlg_create_world.lua
-#, fuzzy
 msgid "Vary river depth"
-msgstr "河流深度"
+msgstr "變化的河流深度"
 
 #: builtin/mainmenu/dlg_create_world.lua
 msgid "Very large caverns deep in the underground"
@@ -626,9 +612,8 @@ msgid "Enabled"
 msgstr "已啟用"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-#, fuzzy
 msgid "Lacunarity"
-msgstr "Lacunarity"
+msgstr "空隙"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 #, fuzzy
@@ -640,9 +625,8 @@ msgid "Offset"
 msgstr "補償"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
-#, fuzzy
-msgid "Persistance"
-msgstr "暫留"
+msgid "Persistence"
+msgstr "持續性"
 
 #: builtin/mainmenu/dlg_settings_advanced.lua
 msgid "Please enter a valid integer."
@@ -751,14 +735,6 @@ msgstr "安裝 Mod:找不到下述項目的真實 Mod 名稱:$1"
 msgid "Install Mod: Unable to find suitable folder name for modpack $1"
 msgstr "安裝 Mod:找不到 $1 Mod 包適合的資料夾名稱"
 
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: Unsupported file type \"$1\" or broken archive"
-msgstr "安裝:「%1」檔案類型不支援,或是封存檔損壞"
-
-#: builtin/mainmenu/pkgmgr.lua
-msgid "Install: file: \"$1\""
-msgstr "安裝:檔案:「$1」"
-
 #: builtin/mainmenu/pkgmgr.lua
 msgid "Unable to find a valid mod or modpack"
 msgstr "找不到有效的 Mod 或 Mod 包"
@@ -793,7 +769,7 @@ msgstr "請嘗試重新啟用公共伺服器清單並檢查您的網際網路連
 
 #: builtin/mainmenu/tab_about.lua
 msgid "About"
-msgstr ""
+msgstr "關於"
 
 #: builtin/mainmenu/tab_about.lua
 msgid "Active Contributors"
@@ -893,13 +869,12 @@ msgid "Host Server"
 msgstr "主機伺服器"
 
 #: builtin/mainmenu/tab_local.lua
-#, fuzzy
 msgid "Install games from ContentDB"
-msgstr "從ContentDB安裝遊戲"
+msgstr "從 ContentDB 安裝遊戲"
 
 #: builtin/mainmenu/tab_local.lua builtin/mainmenu/tab_online.lua
 msgid "Name"
-msgstr ""
+msgstr "名字"
 
 #: builtin/mainmenu/tab_local.lua
 msgid "New"
@@ -938,9 +913,8 @@ msgid "Start Game"
 msgstr "開始遊戲"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Address"
-msgstr "- 地址: "
+msgstr "地址"
 
 #: builtin/mainmenu/tab_online.lua src/client/keycode.cpp
 msgid "Clear"
@@ -956,22 +930,20 @@ msgstr "創造模式"
 
 #. ~ PvP = Player versus Player
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Damage / PvP"
-msgstr "傷害"
+msgstr "傷害 / PvP"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Del. Favorite"
 msgstr "刪除收藏"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Favorites"
 msgstr "收藏"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Incompatible Servers"
-msgstr ""
+msgstr "不相容的伺服器"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Join Game"
@@ -982,16 +954,14 @@ msgid "Ping"
 msgstr "Ping"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Public Servers"
-msgstr "公伺服器"
+msgstr "公伺服器"
 
 #: builtin/mainmenu/tab_online.lua
 msgid "Refresh"
-msgstr ""
+msgstr "重新整理"
 
 #: builtin/mainmenu/tab_online.lua
-#, fuzzy
 msgid "Server Description"
 msgstr "伺服器描述"
 
@@ -1036,13 +1006,12 @@ msgid "Connected Glass"
 msgstr "連接玻璃"
 
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dynamic shadows"
-msgstr "å­\97å\9e\8bé\99°å½±"
+msgstr "å\8b\95æ\85\8bé\99°å½±"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Dynamic shadows: "
-msgstr ""
+msgstr "動態陰影: "
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Fancy Leaves"
@@ -1050,23 +1019,21 @@ msgstr "華麗葉子"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "High"
-msgstr ""
+msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Low"
-msgstr ""
+msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Medium"
-msgstr ""
+msgstr ""
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "Mipmap"
 msgstr "Mip 貼圖"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "Mipmap + Aniso. Filter"
 msgstr "Mip 貼圖 + Aniso. 過濾器"
 
@@ -1075,7 +1042,6 @@ msgid "No Filter"
 msgstr "沒有過濾器"
 
 #: builtin/mainmenu/tab_settings.lua
-#, fuzzy
 msgid "No Mipmap"
 msgstr "沒有 Mip 貼圖"
 
@@ -1135,10 +1101,6 @@ msgstr "平滑光線"
 msgid "Texturing:"
 msgstr "紋理:"
 
-#: builtin/mainmenu/tab_settings.lua
-msgid "To enable shaders the OpenGL driver needs to be used."
-msgstr "要啟用著色器,必須使用 OpenGL 驅動程式。"
-
 #: builtin/mainmenu/tab_settings.lua src/settings_translation_file.cpp
 msgid "Tone Mapping"
 msgstr "色調映射"
@@ -1153,11 +1115,11 @@ msgstr "三線性過濾器"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Ultra High"
-msgstr ""
+msgstr "超高"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Very Low"
-msgstr ""
+msgstr "很低"
 
 #: builtin/mainmenu/tab_settings.lua
 msgid "Waving Leaves"
@@ -1171,7 +1133,7 @@ msgstr "擺動液體"
 msgid "Waving Plants"
 msgstr "植物擺動"
 
-#: src/client/client.cpp
+#: src/client/client.cpp src/client/game.cpp
 msgid "Connection timed out."
 msgstr "連線逾時。"
 
@@ -1200,8 +1162,8 @@ msgid "Connection error (timed out?)"
 msgstr "連線錯誤(逾時?)"
 
 #: src/client/clientlauncher.cpp
-msgid "Could not find or load game \""
-msgstr "找不到或無法載入遊戲 \""
+msgid "Could not find or load game"
+msgstr "找不到或無法載入遊戲"
 
 #: src/client/clientlauncher.cpp
 msgid "Invalid gamespec."
@@ -1243,14 +1205,6 @@ msgstr ""
 msgid "- Address: "
 msgstr "- 地址: "
 
-#: src/client/game.cpp
-msgid "- Creative Mode: "
-msgstr "- 創造模式: "
-
-#: src/client/game.cpp
-msgid "- Damage: "
-msgstr "- 傷害: "
-
 #: src/client/game.cpp
 msgid "- Mode: "
 msgstr "- 模式: "
@@ -1272,6 +1226,15 @@ msgstr "- PvP: "
 msgid "- Server Name: "
 msgstr "- 伺服器名稱: "
 
+#: src/client/game.cpp
+msgid "A serialization error occurred:"
+msgstr "序列化時發生錯誤:"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Access denied. Reason: %s"
+msgstr "存取被拒絕。原因︰%s"
+
 #: src/client/game.cpp
 msgid "Automatic forward disabled"
 msgstr "已停用自動前進"
@@ -1280,6 +1243,22 @@ msgstr "已停用自動前進"
 msgid "Automatic forward enabled"
 msgstr "已啟用自動前進"
 
+#: src/client/game.cpp
+msgid "Block bounds hidden"
+msgstr "區塊邊界隱藏"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for all blocks"
+msgstr "區塊邊界顯示所有區塊"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for current block"
+msgstr "區塊邊界顯示目前區塊"
+
+#: src/client/game.cpp
+msgid "Block bounds shown for nearby blocks"
+msgstr "區塊邊界顯示鄰接區塊"
+
 #: src/client/game.cpp
 msgid "Camera update disabled"
 msgstr "已停用相機更新"
@@ -1288,6 +1267,10 @@ msgstr "已停用相機更新"
 msgid "Camera update enabled"
 msgstr "已啟用相機更新"
 
+#: src/client/game.cpp
+msgid "Can't show block bounds (need 'basic_debug' privilege)"
+msgstr "不能顯示區塊邊界 (需要「basic_debug」權限)"
+
 #: src/client/game.cpp
 msgid "Change Password"
 msgstr "變更密碼"
@@ -1300,6 +1283,10 @@ msgstr "已停用電影模式"
 msgid "Cinematic mode enabled"
 msgstr "已啟用電影模式"
 
+#: src/client/game.cpp
+msgid "Client disconnected"
+msgstr "用戶端已斷線"
+
 #: src/client/game.cpp
 msgid "Client side scripting is disabled"
 msgstr "已停用用戶端指令稿"
@@ -1308,12 +1295,16 @@ msgstr "已停用用戶端指令稿"
 msgid "Connecting to server..."
 msgstr "正在連線至伺服器..."
 
+#: src/client/game.cpp
+msgid "Connection failed for unknown reason"
+msgstr "連線失敗,原因不明"
+
 #: src/client/game.cpp
 msgid "Continue"
 msgstr "繼續"
 
 #: src/client/game.cpp
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "Controls:\n"
 "- %s: move forwards\n"
@@ -1335,16 +1326,21 @@ msgstr ""
 "- %s:向後移動\n"
 "- %s:向左移動\n"
 "- %s:向右移動\n"
-"- %s:跳躍/攀爬\n"
-"- %s:潛行/往下\n"
+"- %s:跳躍/向上攀爬\n"
+"- %s:挖/打\n"
+"- %s:放置/使用\n"
+"- %s:潛行/向下攀爬\n"
 "- %s:丟棄物品\n"
 "- %s:物品欄\n"
 "- 滑鼠:旋轉/觀看\n"
-"- 滑鼠左鍵:挖/推擠\n"
-"- 滑鼠右鍵:放置/使用\n"
 "- 滑鼠滾輪:選取物品\n"
 "- %s:聊天\n"
 
+#: src/client/game.cpp
+#, c-format
+msgid "Couldn't resolve address: %s"
+msgstr "無法解析位址︰%s"
+
 #: src/client/game.cpp
 msgid "Creating client..."
 msgstr "正在建立用戶端..."
@@ -1474,9 +1470,8 @@ msgid "Minimap currently disabled by game or mod"
 msgstr "迷你地圖目前已被遊戲或 Mod 停用"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Multiplayer"
-msgstr "å\96®人遊戲"
+msgstr "å¤\9a人遊戲"
 
 #: src/client/game.cpp
 msgid "Noclip mode disabled"
@@ -1539,7 +1534,6 @@ msgid "Sound muted"
 msgstr "已靜音"
 
 #: src/client/game.cpp
-#, fuzzy
 msgid "Sound system is disabled"
 msgstr "聲音系統已被禁用"
 
@@ -1551,6 +1545,21 @@ msgstr "此編譯版本不支持聲音系統"
 msgid "Sound unmuted"
 msgstr "已取消靜音"
 
+#: src/client/game.cpp
+#, c-format
+msgid "The server is probably running a different version of %s."
+msgstr "此伺服器可能執行的是不同版本的 %s。"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to connect to %s because IPv6 is disabled"
+msgstr "無法連線至 %s 因為 IPv6 已停用"
+
+#: src/client/game.cpp
+#, c-format
+msgid "Unable to listen on %s because IPv6 is disabled"
+msgstr "無法聽取 %s 因為 IPv6 已停用"
+
 #: src/client/game.cpp
 #, c-format
 msgid "Viewing range changed to %d"
@@ -1872,19 +1881,26 @@ msgid "Minimap hidden"
 msgstr "已隱藏迷你地圖"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in radar mode, Zoom x%d"
-msgstr "雷達模式的迷你地圖,放大 1 倍"
+msgstr "雷達模式的迷你地圖,放大 %d 倍"
 
 #: src/client/minimap.cpp
-#, fuzzy, c-format
+#, c-format
 msgid "Minimap in surface mode, Zoom x%d"
-msgstr "表面模式的迷你地圖,放大 1 倍"
+msgstr "表面模式的迷你地圖,放大 %d 倍"
 
 #: src/client/minimap.cpp
-#, fuzzy
 msgid "Minimap in texture mode"
-msgstr "過濾器的最大材質大小"
+msgstr "材質模式的迷你地圖"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Failed to open webpage"
+msgstr "無法開啟網頁"
+
+#: src/gui/guiChatConsole.cpp
+msgid "Opening webpage"
+msgstr "正在開啟網頁"
 
 #: src/gui/guiConfirmRegistration.cpp src/gui/guiPasswordChange.cpp
 msgid "Passwords do not match!"
@@ -1912,9 +1928,8 @@ msgid "Proceed"
 msgstr "繼續"
 
 #: src/gui/guiKeyChangeMenu.cpp
-#, fuzzy
 msgid "\"Aux1\" = climb down"
-msgstr "\"Special\" = 向下攀爬"
+msgstr "\"Aux1\" = 向下攀爬"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Autoforward"
@@ -1926,7 +1941,7 @@ msgstr "自動跳躍"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Aux1"
-msgstr ""
+msgstr "Aux1"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Backward"
@@ -1934,7 +1949,7 @@ msgstr "後退"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Block bounds"
-msgstr ""
+msgstr "區塊邊界"
 
 #: src/gui/guiKeyChangeMenu.cpp
 msgid "Change camera"
@@ -2085,8 +2100,9 @@ msgid "Muted"
 msgstr "已靜音"
 
 #: src/gui/guiVolumeChange.cpp
-msgid "Sound Volume: "
-msgstr "音量: "
+#, c-format
+msgid "Sound Volume: %d%%"
+msgstr "音量:%d%%"
 
 #. ~ Imperative, as in "Enter/type in text".
 #. Don't forget the space.
@@ -2110,12 +2126,13 @@ msgstr ""
 "如停用,虛擬搖桿將會置中於第一個觸碰的位置。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "(Android) Use virtual joystick to trigger \"Aux1\" button.\n"
 "If enabled, virtual joystick will also tap \"Aux1\" button when out of main "
 "circle."
-msgstr "(Android) 使用虛擬搖桿觸發 \"aux\" 按鍵。\n"
+msgstr ""
+"(Android) 使用虛擬搖桿觸發 \"Aux1\" 按鍵。\n"
+"如果啟用,虛擬搖桿在離開主圓圈時也會觸發 \"Aux1\" 按鍵。"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -2154,9 +2171,8 @@ msgid "2D noise that controls the shape/size of rolling hills."
 msgstr "控制波狀丘陵地之形狀或大小的 2D 雜訊值。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "2D noise that controls the shape/size of step mountains."
-msgstr "控制 Step mountains 之形狀或大小的 2D 雜訊值。"
+msgstr "控制階梯山脈之形狀或大小的 2D 雜訊值。"
 
 #: src/settings_translation_file.cpp
 msgid "2D noise that controls the size/occurrence of ridged mountain ranges."
@@ -2270,7 +2286,7 @@ msgstr "ABM 間隔"
 
 #: src/settings_translation_file.cpp
 msgid "ABM time budget"
-msgstr ""
+msgstr "ABM 時間預算"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
@@ -2321,6 +2337,10 @@ msgid ""
 "screens."
 msgstr "調整您螢幕的 DPI 設定(並不只有 X11/Android)例如 4K 螢幕。"
 
+#: src/settings_translation_file.cpp
+msgid "Adjust the detected display density, used for scaling UI elements."
+msgstr "調整偵測到的顯示密度,用來縮放 UI 元件。"
+
 #: src/settings_translation_file.cpp
 #, c-format
 msgid ""
@@ -2385,16 +2405,16 @@ msgid "Apple trees noise"
 msgstr "蘋果樹雜訊"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Arm inertia"
 msgstr "慣性手臂"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Arm inertia, gives a more realistic movement of\n"
 "the arm when the camera moves."
-msgstr "慣性手臂,當相機移動時提供更加真實的手臂運動。"
+msgstr ""
+"慣性手臂,當相機移動時提供\n"
+"更加真實的手臂運動。"
 
 #: src/settings_translation_file.cpp
 msgid "Ask to reconnect after crash"
@@ -2422,16 +2442,14 @@ msgstr ""
 "在地圖區塊中顯示(16 個節點)"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatic forward key"
-msgstr "前進鍵"
+msgstr "自動前進鍵"
 
 #: src/settings_translation_file.cpp
 msgid "Automatically jump up single-node obstacles."
-msgstr ""
+msgstr "自動跳過單個障礙物。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Automatically report to the serverlist."
 msgstr "自動回報到伺服器列表。"
 
@@ -2441,38 +2459,33 @@ msgstr "自動儲存視窗大小"
 
 #: src/settings_translation_file.cpp
 msgid "Autoscaling mode"
-msgstr ""
+msgstr "自動縮放模式"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key"
-msgstr "跳躍鍵"
+msgstr "Aux1 鍵"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Aux1 key for climbing/descending"
-msgstr "用於攀爬/下降的按鍵"
+msgstr "用於攀爬/下降的 Aux1 按鍵"
 
 #: src/settings_translation_file.cpp
 msgid "Backward key"
 msgstr "後退鍵"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Base ground level"
-msgstr "å\9c°é\9d¢é«\98度"
+msgstr "å\9fºç¤\8eå\9c°å¹³é\9d¢"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Base terrain height."
-msgstr "基礎地形高度"
+msgstr "基礎地形高度"
 
 #: src/settings_translation_file.cpp
 msgid "Basic"
 msgstr "基礎"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Basic privileges"
 msgstr "基礎特權"
 
@@ -2501,29 +2514,24 @@ msgid "Biome noise"
 msgstr "生物雜訊"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Block send optimize distance"
 msgstr "區塊傳送最佳化距離"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold and italic font path"
-msgstr "ç­\89寬字型路徑"
+msgstr "ç²\97é«\94è\88\87æ\96\9cé«\94字型路徑"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold and italic monospace font path"
-msgstr "等寬字型路徑"
+msgstr "ç²\97é«\94è\88\87æ\96\9cé«\94ç­\89寬å­\97å\9e\8bè·¯å¾\91"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold font path"
-msgstr "字型路徑"
+msgstr "粗體字型路徑"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Bold monospace font path"
-msgstr "等寬字型路徑"
+msgstr "ç²\97é«\94ç­\89寬å­\97å\9e\8bè·¯å¾\91"
 
 #: src/settings_translation_file.cpp
 msgid "Build inside player"
@@ -2594,9 +2602,8 @@ msgid "Cavern threshold"
 msgstr "洞穴閾值"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Cavern upper limit"
-msgstr "洞穴極限"
+msgstr "洞穴上層極限"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2610,18 +2617,20 @@ msgid "Chat command time message threshold"
 msgstr "聊天訊息踢出閾值"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
+msgid "Chat commands"
+msgstr "聊天指令"
+
+#: src/settings_translation_file.cpp
 msgid "Chat font size"
-msgstr "字型大小"
+msgstr "聊天字型大小"
 
 #: src/settings_translation_file.cpp
 msgid "Chat key"
 msgstr "聊天按鍵"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Chat log level"
-msgstr "除錯記錄等級"
+msgstr "聊天記錄等級"
 
 #: src/settings_translation_file.cpp
 msgid "Chat message count limit"
@@ -2644,8 +2653,8 @@ msgid "Chat toggle key"
 msgstr "聊天切換按鍵"
 
 #: src/settings_translation_file.cpp
-msgid "Chatcommands"
-msgstr "聊天指令"
+msgid "Chat weblinks"
+msgstr "顯示網頁連結"
 
 #: src/settings_translation_file.cpp
 msgid "Chunk size"
@@ -2663,6 +2672,12 @@ msgstr "電影模式按鍵"
 msgid "Clean transparent textures"
 msgstr "清除透明材質"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console "
+"output."
+msgstr "在聊天室主控台輸出中可以點選網頁連結 (滑鼠中鍵或 Ctrl+left-單擊)。"
+
 #: src/settings_translation_file.cpp
 msgid "Client"
 msgstr "用戶端"
@@ -2676,13 +2691,12 @@ msgid "Client modding"
 msgstr "用戶端修改"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Client side modding restrictions"
-msgstr "用戶端修改"
+msgstr "用戶端修改限制"
 
 #: src/settings_translation_file.cpp
 msgid "Client side node lookup range restriction"
-msgstr ""
+msgstr "用戶端節點查詢範圍限制"
 
 #: src/settings_translation_file.cpp
 msgid "Climbing speed"
@@ -2709,9 +2723,8 @@ msgid "Colored fog"
 msgstr "彩色迷霧"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Colored shadows"
-msgstr "彩色迷霧"
+msgstr "彩色陰影"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -2744,6 +2757,22 @@ msgstr ""
 msgid "Command key"
 msgstr "指令按鍵"
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when saving mapblocks to disk.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Compression level to use when sending mapblocks to the client.\n"
+"-1 - use default compression level\n"
+"0 - least compression, fastest\n"
+"9 - best compression, slowest"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Connect glass"
 msgstr "連接玻璃"
@@ -2770,16 +2799,15 @@ msgstr "終端機高度"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Flag Blacklist"
-msgstr ""
+msgstr "ContentDB 旗標黑名單列表"
 
 #: src/settings_translation_file.cpp
 msgid "ContentDB Max Concurrent Downloads"
-msgstr ""
+msgstr "ContentDB 最大並行下載數"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "ContentDB URL"
-msgstr "繼續"
+msgstr "ContentDB URL"
 
 #: src/settings_translation_file.cpp
 msgid "Continuous forward"
@@ -2790,24 +2818,26 @@ msgid ""
 "Continuous forward movement, toggled by autoforward key.\n"
 "Press the autoforward key again or the backwards movement to disable."
 msgstr ""
+"連續前進,通過自動前進鍵切換。\n"
+"再次按自動前進鍵或向後移動即可禁用。"
 
 #: src/settings_translation_file.cpp
 msgid "Controls"
 msgstr "控制"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Controls length of day/night cycle.\n"
 "Examples:\n"
 "72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged."
 msgstr ""
 "控制日/夜循環的長度。\n"
-"範例:72 = 20分鐘,360 = 4分鐘,1 = 24小時,0 = 日/夜/一切保持不變。"
+"範例:\n"
+"72 = 20分鐘,360 = 4分鐘,1 = 24小時,0 = 日/夜/一切保持不變。"
 
 #: src/settings_translation_file.cpp
 msgid "Controls sinking speed in liquid."
-msgstr ""
+msgstr "控制在液體中的下沉速度。"
 
 #: src/settings_translation_file.cpp
 msgid "Controls steepness/depth of lake depressions."
@@ -2823,6 +2853,9 @@ msgid ""
 "Value >= 10.0 completely disables generation of tunnels and avoids the\n"
 "intensive noise calculations."
 msgstr ""
+"控制隧道的寬度,較小的值將創建較寬的隧道。\n"
+"數值 > = 10.0 完全禁用了隧道的生成,並避免了\n"
+"密集的噪聲計算。"
 
 #: src/settings_translation_file.cpp
 msgid "Crash message"
@@ -2837,11 +2870,12 @@ msgid "Crosshair alpha"
 msgstr "十字 alpha 值"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Crosshair alpha (opaqueness, between 0 and 255).\n"
-"Also controls the object crosshair color"
-msgstr "十字 alpha 值(不透明,0 至 255間)。"
+"This also applies to the object crosshair."
+msgstr ""
+"十字 alpha 值(不透明,0 至 255間)。\n"
+"這也會套用到物件十字。"
 
 #: src/settings_translation_file.cpp
 msgid "Crosshair color"
@@ -2852,6 +2886,8 @@ msgid ""
 "Crosshair color (R,G,B).\n"
 "Also controls the object crosshair color"
 msgstr ""
+"十字準線顏色(R,G,B)。\n"
+"還控制物件的十字線顏色"
 
 #: src/settings_translation_file.cpp
 msgid "DPI"
@@ -2866,9 +2902,8 @@ msgid "Debug info toggle key"
 msgstr "除錯資訊切換按鍵"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Debug log file size threshold"
-msgstr "沙漠雜訊閾值"
+msgstr "除錯紀錄檔案大小閾值"
 
 #: src/settings_translation_file.cpp
 msgid "Debug log level"
@@ -2880,7 +2915,7 @@ msgstr "音量減少鍵"
 
 #: src/settings_translation_file.cpp
 msgid "Decrease this to increase liquid resistance to movement."
-msgstr ""
+msgstr "減少此值可增加液體的運動阻力。"
 
 #: src/settings_translation_file.cpp
 msgid "Dedicated server step"
@@ -2915,14 +2950,13 @@ msgid "Default report format"
 msgstr "缺省報告格式"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Default stack size"
-msgstr "預設遊戲"
+msgstr "預設堆疊大小"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Define shadow filtering quality\n"
-"This simulates the soft shadows effect by applying a PCF or poisson disk\n"
+"Define shadow filtering quality.\n"
+"This simulates the soft shadows effect by applying a PCF or Poisson disk\n"
 "but also uses more resources."
 msgstr ""
 
@@ -2957,28 +2991,24 @@ msgid "Defines location and terrain of optional hills and lakes."
 msgstr "定義可選的山丘與湖泊的位置與地形。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the base ground level."
-msgstr "定義樹木區與樹木密度。"
+msgstr "定義基礎地面高度。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the depth of the river channel."
-msgstr "å®\9a義樹æ\9c¨å\8d\80è\88\87樹æ\9c¨å¯\86度。"
+msgstr "å®\9a義河é\81\93ç\9a\84æ·±度。"
 
 #: src/settings_translation_file.cpp
 msgid "Defines the maximal player transfer distance in blocks (0 = unlimited)."
 msgstr "定義玩家最大可傳送的距離,以方塊計(0 = 不限制)。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the width of the river channel."
-msgstr "定義大型河道結構。"
+msgstr "定義河道寬度。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Defines the width of the river valley."
-msgstr "å®\9a義樹ä¸\8aæ\9c\89è\98\8bæ\9e\9cç\9a\84å\8d\80å\9f\9f。"
+msgstr "å®\9a義河谷ç\9a\84寬度。"
 
 #: src/settings_translation_file.cpp
 msgid "Defines tree areas and tree density."
@@ -3024,22 +3054,20 @@ msgid "Desert noise threshold"
 msgstr "沙漠雜訊閾值"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Deserts occur when np_biome exceeds this value.\n"
 "When the 'snowbiomes' flag is enabled, this is ignored."
 msgstr ""
 "當 np_biome 超過此值時,會產生沙漠。\n"
-"當啟用新的生物群系統時,這個將會被忽略。"
+"當啟用新的生物群系統'snowbiomes'時,這個將會被忽略。"
 
 #: src/settings_translation_file.cpp
 msgid "Desynchronize block animation"
 msgstr "異步化方塊動畫"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Dig key"
-msgstr "鍵"
+msgstr "挖掘鍵"
 
 #: src/settings_translation_file.cpp
 msgid "Digging particles"
@@ -3053,6 +3081,10 @@ msgstr "停用反作弊"
 msgid "Disallow empty passwords"
 msgstr "不允許空密碼"
 
+#: src/settings_translation_file.cpp
+msgid "Display Density Scaling Factor"
+msgstr "顯示密度縮放因子"
+
 #: src/settings_translation_file.cpp
 msgid "Domain name of server, to be displayed in the serverlist."
 msgstr "伺服器的域名,將會在伺服器列表中顯示。"
@@ -3076,11 +3108,11 @@ msgstr "轉儲 mapgen 的除錯資訊。"
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon maximum Y"
-msgstr ""
+msgstr "地城最大 X"
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon minimum Y"
-msgstr ""
+msgstr "地城最大 Y"
 
 #: src/settings_translation_file.cpp
 msgid "Dungeon noise"
@@ -3091,6 +3123,8 @@ msgid ""
 "Enable IPv6 support (for both client and server).\n"
 "Required for IPv6 connections to work at all."
 msgstr ""
+"啟用 IPv6 支援(針對客戶端和伺服器)。\n"
+"IPv6 連線需要它才能運作。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3102,7 +3136,14 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Enable colored shadows. \n"
+"Enable Poisson disk filtering.\n"
+"On true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF "
+"filtering."
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid ""
+"Enable colored shadows.\n"
 "On true translucent nodes cast colored shadows. This is expensive."
 msgstr ""
 
@@ -3111,19 +3152,16 @@ msgid "Enable console window"
 msgstr "啟用終端機視窗"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable creative mode for all players"
-msgstr "ç\82ºæ\96°å»ºç«\8bç\9a\84å\9c°å\9c\96å\95\9fç\94¨å\89µé\80 æ¨¡å¼\8fã\80\82"
+msgstr "ç\82ºæ\89\80æ\9c\89ç\9a\84ç\8e©å®¶å\95\9fç\94¨å\89µé\80 æ¨¡å¼\8f"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable joysticks"
 msgstr "啟用搖桿"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid "Enable mod channels support."
-msgstr "啟用 mod 安全性"
+msgstr "啟用 mod 頻道支援。"
 
 #: src/settings_translation_file.cpp
 msgid "Enable mod security"
@@ -3133,26 +3171,21 @@ msgstr "啟用 mod 安全性"
 msgid "Enable players getting damage and dying."
 msgstr "啟用玩家傷害及瀕死。"
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Enable poisson disk filtering.\n"
-"On true uses poisson disk to make \"soft shadows\". Otherwise uses PCF "
-"filtering."
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "Enable random user input (only used for testing)."
 msgstr "啟用隨機使用者輸入(僅供測試使用)。"
 
 #: src/settings_translation_file.cpp
 msgid "Enable register confirmation"
-msgstr ""
+msgstr "啟用註冊確認"
 
 #: src/settings_translation_file.cpp
 msgid ""
 "Enable register confirmation when connecting to server.\n"
 "If disabled, new account will be registered automatically."
 msgstr ""
+"連線到伺服器時啟用註冊確認。\n"
+"如果停用,會自動註冊新的帳號。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3200,15 +3233,14 @@ msgstr ""
 "舉例來說:設為 0 就不會有視野晃動;1.0 是一般情況;2.0 為雙倍。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
 "Enable/disable running an IPv6 server.\n"
 "Ignored if bind_address is set.\n"
 "Needs enable_ipv6 to be enabled."
 msgstr ""
-"啟用/停用執行 IPv6 伺服器。IPv6 伺服器可能會限制只有\n"
-"IPv6 用戶端才能連線,取決於系統設定。\n"
-"當 bind_address 被設定時將會被忽略。"
+"啟用/停用執行 IPv6 伺服器。\n"
+"當 bind_address 被設定時將會被忽略。\n"
+"需要啟用 enable_ipv6。"
 
 #: src/settings_translation_file.cpp
 msgid ""
@@ -3238,6 +3270,12 @@ msgid ""
 "Changing this setting requires a restart."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Enables tradeoffs that reduce CPU load or increase rendering performance\n"
+"at the expense of minor visual glitches that do not impact game playability."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Engine profiling data print interval"
 msgstr "引擎性能資料印出間隔"
@@ -3442,11 +3480,15 @@ msgid "Font size"
 msgstr "字型大小"
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the default font in point (pt)."
+msgid "Font size divisible by"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Font size of the monospace font in point (pt)."
+msgid "Font size of the default font where 1 unit = 1 pixel at 96 DPI"
+msgstr ""
+
+#: src/settings_translation_file.cpp
+msgid "Font size of the monospace font where 1 unit = 1 pixel at 96 DPI"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -3455,6 +3497,17 @@ msgid ""
 "Value 0 will use the default font size."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"For pixel-style fonts that do not scale well, this ensures that font sizes "
+"used\n"
+"with this font will always be divisible by this value, in pixels. For "
+"instance,\n"
+"a pixel font 16 pixels tall should have this set to 16, so it will only ever "
+"be\n"
+"sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Format of player chat messages. The following strings are valid "
@@ -3520,11 +3573,6 @@ msgstr "碎形類型"
 msgid "Fraction of the visible distance at which fog starts to be rendered"
 msgstr "開始呈現霧氣的可見距離分數"
 
-#: src/settings_translation_file.cpp
-#, fuzzy
-msgid "FreeType fonts"
-msgstr "Freetype 字型"
-
 #: src/settings_translation_file.cpp
 msgid ""
 "From how far blocks are generated for clients, stated in mapblocks (16 "
@@ -3574,7 +3622,7 @@ msgstr "全域回呼"
 msgid ""
 "Global map generation attributes.\n"
 "In Mapgen v6 the 'decorations' flag controls all decorations except trees\n"
-"and junglegrass, in all other mapgens this flag controls all decorations."
+"and jungle grass, in all other mapgens this flag controls all decorations."
 msgstr ""
 "全域地圖產生屬性。\n"
 "在 Mapgen v6 中,「decorations」旗標控制所有除了樹木\n"
@@ -4044,7 +4092,8 @@ msgstr ""
 "這通常僅被核心/內建貢獻者需要"
 
 #: src/settings_translation_file.cpp
-msgid "Instrument chatcommands on registration."
+#, fuzzy
+msgid "Instrument chat commands on registration."
 msgstr "分析登錄的聊天指令。"
 
 #: src/settings_translation_file.cpp
@@ -4133,7 +4182,7 @@ msgstr "搖桿按鈕重覆間隔"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Joystick deadzone"
+msgid "Joystick dead zone"
 msgstr "搖桿類型"
 
 #: src/settings_translation_file.cpp
@@ -5251,7 +5300,7 @@ msgstr "地圖儲存間隔"
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "Map update time"
+msgid "Map shadows update frames"
 msgstr "液體更新 tick"
 
 #: src/settings_translation_file.cpp
@@ -5575,7 +5624,8 @@ msgid "Mod channels"
 msgstr ""
 
 #: src/settings_translation_file.cpp
-msgid "Modifies the size of the hudbar elements."
+#, fuzzy
+msgid "Modifies the size of the HUD elements."
 msgstr "修改 hudbar 元素的大小。"
 
 #: src/settings_translation_file.cpp
@@ -5586,6 +5636,11 @@ msgstr "等寬字型路徑"
 msgid "Monospace font size"
 msgstr "等寬字型大小"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Monospace font size divisible by"
+msgstr "等寬字型大小"
+
 #: src/settings_translation_file.cpp
 msgid "Mountain height noise"
 msgstr "山高度 雜訊"
@@ -5713,9 +5768,10 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "Number of extra blocks that can be loaded by /clearobjects at once.\n"
-"This is a trade-off between sqlite transaction overhead and\n"
+"This is a trade-off between SQLite transaction overhead and\n"
 "memory consumption (4096=100MB, as a rule of thumb)."
 msgstr ""
 "可被 /clearobjects 一次載入的額外區塊數量。\n"
@@ -5742,11 +5798,13 @@ msgid ""
 "open."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid "Optional override for chat weblink color."
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
-"Path of the fallback font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path of the fallback font. Must be a TrueType font.\n"
 "This font will be used for certain languages or if the default font is "
 "unavailable."
 msgstr ""
@@ -5769,17 +5827,13 @@ msgstr "材質目錄的路徑。所有材質都會先從這裡搜尋。"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the default font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the default font. Must be a TrueType font.\n"
 "The fallback font will be used if the font cannot be loaded."
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Path to the monospace font.\n"
-"If “freetype” setting is enabled: Must be a TrueType font.\n"
-"If “freetype” setting is disabled: Must be a bitmap or XML vectors font.\n"
+"Path to the monospace font. Must be a TrueType font.\n"
 "This font is used for e.g. the console and profiler screen."
 msgstr ""
 
@@ -5893,9 +5947,9 @@ msgstr ""
 #: src/settings_translation_file.cpp
 msgid ""
 "Prometheus listener address.\n"
-"If minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
+"If Minetest is compiled with ENABLE_PROMETHEUS option enabled,\n"
 "enable metrics listener for Prometheus on that address.\n"
-"Metrics can be fetch on http://127.0.0.1:30000/metrics"
+"Metrics can be fetched on http://127.0.0.1:30000/metrics"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6231,26 +6285,18 @@ msgid ""
 "Lower value means lighter shadows, higher value means darker shadows."
 msgstr ""
 
-#: src/settings_translation_file.cpp
-msgid ""
-"Set the shadow update time.\n"
-"Lower value means shadows and map updates faster, but it consume more "
-"resources.\n"
-"Minimun value 0.001 seconds max value 0.2 seconds"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid ""
 "Set the soft shadow radius size.\n"
-"Lower values mean sharper shadows bigger values softer.\n"
-"Minimun value 1.0 and max value 10.0"
+"Lower values mean sharper shadows, bigger values mean softer shadows.\n"
+"Minimum value: 1.0; maximum value: 10.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Set the tilt of Sun/Moon orbit in degrees\n"
+"Set the tilt of Sun/Moon orbit in degrees.\n"
 "Value of 0 means no tilt / vertical orbit.\n"
-"Minimun value 0.0 and max value 60.0"
+"Minimum value: 0.0; maximum value: 60.0"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6362,7 +6408,7 @@ msgstr ""
 "變更後必須重新啟動以使其生效。"
 
 #: src/settings_translation_file.cpp
-msgid "Show nametag backgrounds by default"
+msgid "Show name tag backgrounds by default"
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6479,6 +6525,14 @@ msgid ""
 "items."
 msgstr ""
 
+#: src/settings_translation_file.cpp
+msgid ""
+"Spread a complete update of shadow map over given amount of frames.\n"
+"Higher values might make shadows laggy, lower values\n"
+"will consume more resources.\n"
+"Minimum value: 1; maximum value: 16"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid ""
 "Spread of light curve boost range.\n"
@@ -6599,7 +6653,7 @@ msgstr "材質路徑"
 msgid ""
 "Texture size to render the shadow map on.\n"
 "This must be a power of two.\n"
-"Bigger numbers create better shadowsbut it is also more expensive."
+"Bigger numbers create better shadows but it is also more expensive."
 msgstr ""
 
 #: src/settings_translation_file.cpp
@@ -6618,7 +6672,7 @@ msgstr ""
 
 #: src/settings_translation_file.cpp
 #, fuzzy
-msgid "The deadzone of the joystick"
+msgid "The dead zone of the joystick"
 msgstr "要使用的搖桿的識別碼"
 
 #: src/settings_translation_file.cpp
@@ -6690,9 +6744,10 @@ msgid ""
 msgstr ""
 
 #: src/settings_translation_file.cpp
+#, fuzzy
 msgid ""
 "The sensitivity of the joystick axes for moving the\n"
-"ingame view frustum around."
+"in-game view frustum around."
 msgstr ""
 "在遊戲中,視野四處移動時的\n"
 "搖桿靈敏度。"
@@ -6802,6 +6857,10 @@ msgstr "工具提示延遲"
 msgid "Touch screen threshold"
 msgstr "海灘雜訊閾值"
 
+#: src/settings_translation_file.cpp
+msgid "Tradeoffs for performance"
+msgstr ""
+
 #: src/settings_translation_file.cpp
 msgid "Trees noise"
 msgstr "樹林雜訊"
@@ -6881,7 +6940,7 @@ msgstr "當縮放材質時使用雙線性過濾。"
 
 #: src/settings_translation_file.cpp
 msgid ""
-"Use mip mapping to scale textures. May slightly increase performance,\n"
+"Use mipmapping to scale textures. May slightly increase performance,\n"
 "especially when using a high resolution texture pack.\n"
 "Gamma correct downscaling is not supported."
 msgstr ""
@@ -7085,6 +7144,11 @@ msgstr "波動的水長度"
 msgid "Waving plants"
 msgstr "植物擺動"
 
+#: src/settings_translation_file.cpp
+#, fuzzy
+msgid "Weblink color"
+msgstr "色彩選取框"
+
 #: src/settings_translation_file.cpp
 msgid ""
 "When gui_scaling_filter is true, all GUI images need to be\n"
@@ -7114,7 +7178,7 @@ msgid ""
 "can be blurred, so automatically upscale them with nearest-neighbor\n"
 "interpolation to preserve crisp pixels. This sets the minimum texture size\n"
 "for the upscaled textures; higher values look sharper, but require more\n"
-"memory.  Powers of 2 are recommended. This setting is ONLY applies if\n"
+"memory. Powers of 2 are recommended. This setting is ONLY applied if\n"
 "bilinear/trilinear/anisotropic filtering is enabled.\n"
 "This is also used as the base node texture size for world-aligned\n"
 "texture autoscaling."
@@ -7128,16 +7192,8 @@ msgstr ""
 "已啟用。"
 
 #: src/settings_translation_file.cpp
-#, fuzzy
 msgid ""
-"Whether FreeType fonts are used, requires FreeType support to be compiled "
-"in.\n"
-"If disabled, bitmap and XML vectors fonts are used instead."
-msgstr "是否使用 freetype 字型,需要將 freetype 支援編譯進來。"
-
-#: src/settings_translation_file.cpp
-msgid ""
-"Whether nametag backgrounds should be shown by default.\n"
+"Whether name tag backgrounds should be shown by default.\n"
 "Mods may still set a background."
 msgstr ""
 
@@ -7277,24 +7333,6 @@ msgstr "較低地形與湖底的 Y 高度。"
 msgid "Y-level of seabed."
 msgstr "海底的 Y 高度。"
 
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when saving mapblocks to disk.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
-#: src/settings_translation_file.cpp
-msgid ""
-"ZLib compression level to use when sending mapblocks to the client.\n"
-"-1 - Zlib's default compression level\n"
-"0 - no compresson, fastest\n"
-"9 - best compression, slowest\n"
-"(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)"
-msgstr ""
-
 #: src/settings_translation_file.cpp
 msgid "cURL file download timeout"
 msgstr "cURL 檔案下載逾時"
@@ -7308,6 +7346,12 @@ msgstr "cURL 逾時"
 msgid "cURL parallel limit"
 msgstr "cURL 並行限制"
 
+#~ msgid "- Creative Mode: "
+#~ msgstr "- 創造模式: "
+
+#~ msgid "- Damage: "
+#~ msgstr "- 傷害: "
+
 #~ msgid ""
 #~ "0 = parallax occlusion with slope information (faster).\n"
 #~ "1 = relief mapping (slower, more accurate)."
@@ -7450,6 +7494,10 @@ msgstr "cURL 並行限制"
 #~ msgid "Font shadow alpha (opaqueness, between 0 and 255)."
 #~ msgstr "字型陰影 alpha(不透明度,介於 0 到 255)。"
 
+#, fuzzy
+#~ msgid "FreeType fonts"
+#~ msgstr "Freetype 字型"
+
 #~ msgid "Full screen BPP"
 #~ msgstr "全螢幕 BPP"
 
@@ -7468,6 +7516,9 @@ msgstr "cURL 並行限制"
 #~ msgid "IPv6 support."
 #~ msgstr "IPv6 支援。"
 
+#~ msgid "Install: file: \"$1\""
+#~ msgstr "安裝:檔案:「$1」"
+
 #, fuzzy
 #~ msgid "Lava depth"
 #~ msgstr "大型洞穴深度"
@@ -7587,6 +7638,9 @@ msgstr "cURL 並行限制"
 #~ msgid "This font will be used for certain languages."
 #~ msgstr "這個字型將會被用於特定的語言。"
 
+#~ msgid "To enable shaders the OpenGL driver needs to be used."
+#~ msgstr "要啟用著色器,必須使用 OpenGL 驅動程式。"
+
 #~ msgid "Toggle Cinematic"
 #~ msgstr "切換過場動畫"
 
@@ -7607,6 +7661,13 @@ msgstr "cURL 並行限制"
 #~ msgid "Waving water"
 #~ msgstr "波動的水"
 
+#, fuzzy
+#~ msgid ""
+#~ "Whether FreeType fonts are used, requires FreeType support to be compiled "
+#~ "in.\n"
+#~ "If disabled, bitmap and XML vectors fonts are used instead."
+#~ msgstr "是否使用 freetype 字型,需要將 freetype 支援編譯進來。"
+
 #, fuzzy
 #~ msgid "Y of upper limit of lava in large caves."
 #~ msgstr "大型偽隨機洞穴的 Y 上限。"
@@ -7620,5 +7681,9 @@ msgstr "cURL 並行限制"
 #~ msgid "Yes"
 #~ msgstr "是"
 
+#, fuzzy
+#~ msgid "You died."
+#~ msgstr "您已死亡"
+
 #~ msgid "needs_fallback_font"
 #~ msgstr "yes"
index dc2072d117db8fef4710a7e77f050268b02e5775..7bba68a643e02dab2391d13bedcedf4a2349b45c 100644 (file)
@@ -98,34 +98,17 @@ if(BUILD_CLIENT AND ENABLE_SOUND)
        endif()
 endif()
 
-
-option(ENABLE_GLES "Use OpenGL ES instead of OpenGL" FALSE)
+# TODO: this should be removed one day, we can enable it unconditionally
+option(ENABLE_GLES "Enable extra support code for OpenGL ES" FALSE)
 mark_as_advanced(ENABLE_GLES)
-if(BUILD_CLIENT)
-       # transitive dependency from Irrlicht (see longer explanation below)
-       if(NOT WIN32)
-               if(ENABLE_GLES)
-                       find_package(OpenGLES2 REQUIRED)
-               else()
-                       set(OPENGL_GL_PREFERENCE "LEGACY" CACHE STRING
-                               "See CMake Policy CMP0072 for reference. GLVND is broken on some nvidia setups")
-                       set(OpenGL_GL_PREFERENCE ${OPENGL_GL_PREFERENCE})
 
-                       find_package(OpenGL REQUIRED)
-               endif()
-       endif()
+option(ENABLE_TOUCH "Enable Touchscreen support" FALSE)
+if(ENABLE_TOUCH)
+       add_definitions(-DHAVE_TOUCHSCREENGUI)
 endif()
 
-
-option(ENABLE_FREETYPE "Enable FreeType2 (TrueType fonts and basic unicode support)" TRUE)
-set(USE_FREETYPE FALSE)
-
-if(BUILD_CLIENT AND ENABLE_FREETYPE)
-       find_package(Freetype)
-       if(FREETYPE_FOUND)
-               message(STATUS "Freetype enabled.")
-               set(USE_FREETYPE TRUE)
-       endif()
+if(BUILD_CLIENT)
+       find_package(Freetype REQUIRED)
 endif()
 
 option(ENABLE_CURSES "Enable ncurses console" TRUE)
@@ -270,12 +253,14 @@ if(WIN32)
        else() # Probably MinGW = GCC
                set(PLATFORM_LIBS "")
        endif()
-       set(PLATFORM_LIBS ws2_32.lib version.lib shlwapi.lib ${PLATFORM_LIBS})
+       set(PLATFORM_LIBS ws2_32.lib version.lib shlwapi.lib winmm.lib ${PLATFORM_LIBS})
+
+       set(EXTRA_DLL "" CACHE FILEPATH "Optional paths to additional DLLs that should be packaged")
 
        # DLLs are automatically copied to the output directory by vcpkg when VCPKG_APPLOCAL_DEPS=ON
        if(NOT VCPKG_APPLOCAL_DEPS)
-               find_file(ZLIB_DLL NAMES "" DOC "Path to Zlib DLL for installation (optional)")
-               find_file(ZSTD_DLL NAMES "" DOC "Path to Zstd DLL for installation (optional)")
+               set(ZLIB_DLL "" CACHE FILEPATH "Path to Zlib DLL for installation (optional)")
+               set(ZSTD_DLL "" CACHE FILEPATH "Path to Zstd DLL for installation (optional)")
                if(ENABLE_SOUND)
                        set(OPENAL_DLL "" CACHE FILEPATH "Path to OpenAL32.dll for installation (optional)")
                        set(OGG_DLL "" CACHE FILEPATH "Path to libogg.dll for installation (optional)")
@@ -288,7 +273,6 @@ if(WIN32)
                        set(LUA_DLL "" CACHE FILEPATH "Path to luajit-5.1.dll for installation (optional)")
                endif()
        endif()
-
 else()
        # Unix probably
        if(BUILD_CLIENT)
@@ -346,6 +330,7 @@ add_subdirectory(mapgen)
 add_subdirectory(network)
 add_subdirectory(script)
 add_subdirectory(unittest)
+add_subdirectory(benchmark)
 add_subdirectory(util)
 add_subdirectory(irrlicht_changes)
 add_subdirectory(server)
@@ -428,6 +413,9 @@ if(BUILD_UNITTESTS)
        set(common_SRCS ${common_SRCS} ${UNITTEST_SRCS})
 endif()
 
+if(BUILD_BENCHMARKS)
+       set(common_SRCS ${common_SRCS} ${BENCHMARK_SRCS})
+endif()
 
 # This gives us the icon and file version information
 if(WIN32)
@@ -468,6 +456,10 @@ if(BUILD_UNITTESTS)
        set(client_SRCS ${client_SRCS} ${UNITTEST_CLIENT_SRCS})
 endif()
 
+if(BUILD_BENCHMARKS)
+       set(client_SRCS ${client_SRCS} ${BENCHMARK_CLIENT_SRCS})
+endif()
+
 list(SORT client_SRCS)
 
 # Server sources
@@ -486,23 +478,28 @@ endif()
 include_directories(
        ${PROJECT_BINARY_DIR}
        ${PROJECT_SOURCE_DIR}
+       ${PROJECT_SOURCE_DIR}/script
+)
+include_directories(SYSTEM
        ${ZLIB_INCLUDE_DIR}
        ${ZSTD_INCLUDE_DIR}
-       ${SOUND_INCLUDE_DIRS}
        ${SQLITE3_INCLUDE_DIR}
        ${LUA_INCLUDE_DIR}
        ${GMP_INCLUDE_DIR}
        ${JSON_INCLUDE_DIR}
-       ${X11_INCLUDE_DIR}
-       ${PROJECT_SOURCE_DIR}/script
+       ${LUA_BIT_INCLUDE_DIR}
 )
 
 if(USE_GETTEXT)
        include_directories(${GETTEXT_INCLUDE_DIR})
 endif()
 
-if(USE_FREETYPE)
-       include_directories(${FREETYPE_INCLUDE_DIRS})
+if(BUILD_CLIENT)
+       include_directories(SYSTEM
+               ${FREETYPE_INCLUDE_DIRS}
+               ${SOUND_INCLUDE_DIRS}
+               ${X11_INCLUDE_DIR}
+       )
 endif()
 
 if(USE_CURL)
@@ -530,6 +527,8 @@ if(BUILD_CLIENT)
                ${LUA_LIBRARY}
                ${GMP_LIBRARY}
                ${JSON_LIBRARY}
+               ${LUA_BIT_LIBRARY}
+               ${FREETYPE_LIBRARY}
                ${PLATFORM_LIBS}
        )
        if(NOT USE_LUAJIT)
@@ -540,18 +539,6 @@ if(BUILD_CLIENT)
                )
        endif()
 
-       if(ENABLE_GLES)
-               target_link_libraries(
-                       ${PROJECT_NAME}
-                       ${OPENGLES2_LIBRARIES}
-                       ${EGL_LIBRARIES}
-               )
-       else()
-               target_link_libraries(
-                       ${PROJECT_NAME}
-                       ${OPENGL_LIBRARIES}
-               )
-       endif()
        if(USE_GETTEXT)
                target_link_libraries(
                        ${PROJECT_NAME}
@@ -564,17 +551,11 @@ if(BUILD_CLIENT)
                        ${CURL_LIBRARY}
                )
        endif()
-       if(USE_FREETYPE)
-               if(FREETYPE_PKGCONFIG_FOUND)
-                       set_target_properties(${PROJECT_NAME}
-                               PROPERTIES
-                               COMPILE_FLAGS "${FREETYPE_CFLAGS_STR}"
-                       )
-               endif()
-               target_link_libraries(
-                       ${PROJECT_NAME}
-                       ${FREETYPE_LIBRARY}
-               )
+       if(FREETYPE_PKGCONFIG_FOUND)
+               set_target_properties(${PROJECT_NAME}
+                       PROPERTIES
+                       COMPILE_FLAGS "${FREETYPE_CFLAGS_STR}"
+       )
        endif()
        if (USE_CURSES)
                target_link_libraries(${PROJECT_NAME} ${CURSES_LIBRARIES})
@@ -594,6 +575,9 @@ if(BUILD_CLIENT)
        if (USE_SPATIAL)
                target_link_libraries(${PROJECT_NAME} ${SPATIAL_LIBRARY})
        endif()
+       if(BUILD_BENCHMARKS)
+               target_link_libraries(${PROJECT_NAME} catch2)
+       endif()
 endif(BUILD_CLIENT)
 
 
@@ -612,6 +596,7 @@ if(BUILD_SERVER)
                ${SQLITE3_LIBRARY}
                ${JSON_LIBRARY}
                ${LUA_LIBRARY}
+               ${LUA_BIT_LIBRARY}
                ${GMP_LIBRARY}
                ${PLATFORM_LIBS}
        )
@@ -652,6 +637,9 @@ if(BUILD_SERVER)
                        ${CURL_LIBRARY}
                )
        endif()
+       if(BUILD_BENCHMARKS)
+               target_link_libraries(${PROJECT_NAME}server catch2)
+       endif()
 endif(BUILD_SERVER)
 
 # Blacklisted locales that don't work.
@@ -719,15 +707,13 @@ if(MSVC)
        endif()
 else()
        # GCC or compatible compilers such as Clang
-       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+       set(WARNING_FLAGS "-Wall -Wextra")
+       set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-unused-parameter -Wno-implicit-fallthrough")
        if(WARN_ALL)
-               set(RELEASE_WARNING_FLAGS "-Wall")
+               set(RELEASE_WARNING_FLAGS "${WARNING_FLAGS}")
        else()
                set(RELEASE_WARNING_FLAGS "")
        endif()
-       if(CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang")
-               set(WARNING_FLAGS "${WARNING_FLAGS} -Wsign-compare")
-       endif()
 
        if(APPLE AND USE_LUAJIT)
                # required per http://luajit.org/install.html
@@ -738,7 +724,7 @@ else()
                        # Move text segment below LuaJIT's 47-bit limit (see issue #9367)
                        if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
                                # FreeBSD uses lld, and lld does not support -Ttext-segment, suggesting
-                               # --image-base instead. Not sure if it's equivalent change for the purpose 
+                               # --image-base instead. Not sure if it's equivalent change for the purpose
                                # but at least if fixes build on FreeBSD/aarch64
                                # XXX: the condition should also be changed to check for lld regardless of
                                # os, bit CMake doesn't have anything like CMAKE_LINKER_IS_LLD yet
@@ -759,7 +745,17 @@ else()
        # - we don't deal with Inf/NaN or signed zero
        set(MATH_FLAGS "-fno-math-errno -fno-trapping-math -ffinite-math-only -fno-signed-zeros")
 
-       set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} ${OTHER_FLAGS} -Wall -pipe -funroll-loops")
+       # Enable SSE for floating point math on 32-bit x86 by default
+       # reasoning see minetest issue #11810 and https://gcc.gnu.org/wiki/FloatingPointMath
+       if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+               check_c_source_compiles("#ifndef __i686__\n#error\n#endif\nint main(){}" IS_I686)
+               if(IS_I686)
+                       message(STATUS "Detected Intel x86: using SSE instead of x87 FPU")
+                       set(OTHER_FLAGS "${OTHER_FLAGS} -mfpmath=sse -msse")
+               endif()
+       endif()
+
+       set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${OTHER_FLAGS} -pipe -funroll-loops")
        if(CMAKE_SYSTEM_NAME MATCHES "(Darwin|BSD|DragonFly)")
                set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os")
        else()
@@ -772,8 +768,9 @@ else()
                        set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MATH_FLAGS}")
                endif()
        endif()
-       set(CMAKE_CXX_FLAGS_SEMIDEBUG "-g -O1 -Wall ${WARNING_FLAGS} ${OTHER_FLAGS}")
-       set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall ${WARNING_FLAGS} ${OTHER_FLAGS}")
+       set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -g")
+       set(CMAKE_CXX_FLAGS_SEMIDEBUG "-g -O1 ${WARNING_FLAGS} ${OTHER_FLAGS}")
+       set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 ${WARNING_FLAGS} ${OTHER_FLAGS}")
 
        if(USE_GPROF)
                set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg")
@@ -788,6 +785,9 @@ endif()
 # Installation
 
 if(WIN32)
+       if(EXTRA_DLL)
+               install(FILES ${EXTRA_DLL} DESTINATION ${BINDIR})
+       endif()
        if(VCPKG_APPLOCAL_DEPS)
                # Collect the dll's from the output path
                install(DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/Release/
@@ -840,13 +840,14 @@ if(WIN32)
                if(LUA_DLL)
                        install(FILES ${LUA_DLL} DESTINATION ${BINDIR})
                endif()
-               if(BUILD_CLIENT AND IRRLICHT_DLL)
-                       install(FILES ${IRRLICHT_DLL} DESTINATION ${BINDIR})
-               endif()
                if(BUILD_CLIENT AND USE_GETTEXT AND GETTEXT_DLL)
                        install(FILES ${GETTEXT_DLL} DESTINATION ${BINDIR})
                endif()
        endif()
+
+       if(BUILD_CLIENT AND IRRLICHT_DLL)
+               install(FILES ${IRRLICHT_DLL} DESTINATION ${BINDIR})
+       endif()
 endif()
 
 if(BUILD_CLIENT)
@@ -873,14 +874,8 @@ if(BUILD_CLIENT)
                endforeach()
        endif()
 
-       # Install necessary fonts depending on configuration
-       if(USE_FREETYPE)
-               install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../fonts" DESTINATION "${SHAREDIR}"
-                               FILES_MATCHING PATTERN "*.ttf" PATTERN "*.txt")
-       else()
-               install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../fonts" DESTINATION "${SHAREDIR}"
-                               FILES_MATCHING PATTERN "*.png" PATTERN "*.xml")
-       endif()
+       install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../fonts" DESTINATION "${SHAREDIR}"
+                       FILES_MATCHING PATTERN "*.ttf" PATTERN "*.txt")
 endif(BUILD_CLIENT)
 
 if(BUILD_SERVER)
diff --git a/src/benchmark/CMakeLists.txt b/src/benchmark/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5feba34
--- /dev/null
@@ -0,0 +1,7 @@
+set (BENCHMARK_SRCS
+       ${CMAKE_CURRENT_SOURCE_DIR}/benchmark.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/benchmark_serialize.cpp
+       PARENT_SCOPE)
+
+set (BENCHMARK_CLIENT_SRCS
+       PARENT_SCOPE)
diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp
new file mode 100644 (file)
index 0000000..0bc2af3
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+Minetest
+Copyright (C) 2022 Minetest Authors
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "benchmark/benchmark.h"
+
+// This must be set in just this file
+#define CATCH_CONFIG_RUNNER
+#include "benchmark_setup.h"
+
+int run_benchmarks()
+{
+       int argc = 1;
+       const char *argv[] = { "MinetestBenchmark", NULL };
+       int errCount = Catch::Session().run(argc, argv);
+       return errCount ? 1 : 0;
+}
diff --git a/src/benchmark/benchmark.h b/src/benchmark/benchmark.h
new file mode 100644 (file)
index 0000000..45dd9b6
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+Minetest
+Copyright (C) 2022 Minetest Authors
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+#include "config.h"
+
+#if BUILD_BENCHMARKS
+extern int run_benchmarks();
+#endif
diff --git a/src/benchmark/benchmark_serialize.cpp b/src/benchmark/benchmark_serialize.cpp
new file mode 100644 (file)
index 0000000..97cc7d5
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+Minetest
+Copyright (C) 2022 Minetest Authors
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "benchmark_setup.h"
+#include "util/serialize.h"
+#include <sstream>
+#include <ios>
+
+// Builds a string of exactly `length` characters by repeating `s` (rest cut off)
+static std::string makeRepeatTo(const std::string &s, size_t length)
+{
+       std::string v;
+       v.reserve(length + s.size());
+       for (size_t i = 0; i < length; i += s.size()) {
+               v += s;
+       }
+       v.resize(length);
+       return v;
+}
+
+#define BENCH3(_label, _chars, _length, _lengthlabel) \
+       BENCHMARK_ADVANCED("serializeJsonStringIfNeeded_" _lengthlabel "_" _label)(Catch::Benchmark::Chronometer meter) { \
+               std::string s = makeRepeatTo(_chars, _length); \
+               meter.measure([&] { return serializeJsonStringIfNeeded(s); }); \
+       }; \
+       BENCHMARK_ADVANCED("deSerializeJsonStringIfNeeded_" _lengthlabel "_" _label)(Catch::Benchmark::Chronometer meter) { \
+               std::string s = makeRepeatTo(_chars, _length); \
+               std::string serialized = serializeJsonStringIfNeeded(s); \
+               std::istringstream is(serialized, std::ios::binary); \
+               meter.measure([&] { \
+                       is.clear(); \
+                       is.seekg(0, std::ios::beg); \
+                       return deSerializeJsonStringIfNeeded(is); \
+               }); \
+       };
+
+/* Both with and without a space character (' ') */
+#define BENCH2(_label, _chars, _length, _lengthlabel) \
+       BENCH3(_label, _chars, _length, _lengthlabel) \
+       BENCH3(_label "_with_space", " " _chars, _length, _lengthlabel) \
+
+/* Iterate over input lengths */
+#define BENCH1(_label, _chars) \
+       BENCH2(_label, _chars, 10, "small") \
+       BENCH2(_label, _chars, 10000, "large")
+
+/* Iterate over character sets */
+#define BENCH_ALL() \
+       BENCH1("alpha", "abcdefghijklmnopqrstuvwxyz") \
+       BENCH1("escaped", "\"\\/\b\f\n\r\t") \
+       BENCH1("nonascii", "\xf0\xff")
+
+TEST_CASE("benchmark_serialize") {
+       BENCH_ALL()
+}
diff --git a/src/benchmark/benchmark_setup.h b/src/benchmark/benchmark_setup.h
new file mode 100644 (file)
index 0000000..34a4eca
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+Minetest
+Copyright (C) 2022 Minetest Authors
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#define CATCH_CONFIG_ENABLE_BENCHMARKING
+#define CATCH_CONFIG_CONSOLE_WIDTH 160
+#include <catch.hpp>
index 162622abe40216a044df7bf93272e1d58c30a063..92df038e83ab0f69d42ab07c699d526fccfe271a 100644 (file)
@@ -50,6 +50,8 @@ ChatBuffer::ChatBuffer(u32 scrollback):
 
 void ChatBuffer::addLine(const std::wstring &name, const std::wstring &text)
 {
+       m_lines_modified = true;
+
        ChatLine line(name, text);
        m_unformatted.push_back(line);
 
@@ -72,6 +74,7 @@ void ChatBuffer::clear()
        m_unformatted.clear();
        m_formatted.clear();
        m_scroll = 0;
+       m_lines_modified = true;
 }
 
 u32 ChatBuffer::getLineCount() const
@@ -99,14 +102,11 @@ void ChatBuffer::deleteOldest(u32 count)
        u32 del_unformatted = 0;
        u32 del_formatted = 0;
 
-       while (count > 0 && del_unformatted < m_unformatted.size())
-       {
+       while (count > 0 && del_unformatted < m_unformatted.size()) {
                ++del_unformatted;
 
                // keep m_formatted in sync
-               if (del_formatted < m_formatted.size())
-               {
-
+               if (del_formatted < m_formatted.size()) {
                        sanity_check(m_formatted[del_formatted].first);
                        ++del_formatted;
                        while (del_formatted < m_formatted.size() &&
@@ -120,6 +120,9 @@ void ChatBuffer::deleteOldest(u32 count)
        m_unformatted.erase(m_unformatted.begin(), m_unformatted.begin() + del_unformatted);
        m_formatted.erase(m_formatted.begin(), m_formatted.begin() + del_formatted);
 
+       if (del_unformatted > 0)
+               m_lines_modified = true;
+
        if (at_bottom)
                m_scroll = getBottomScrollPos();
        else
@@ -139,11 +142,6 @@ u32 ChatBuffer::getRows() const
        return m_rows;
 }
 
-void ChatBuffer::scrollTop()
-{
-       m_scroll = getTopScrollPos();
-}
-
 void ChatBuffer::reformat(u32 cols, u32 rows)
 {
        if (cols == 0 || rows == 0)
index aabb0821eccdeb133900dd381d856aacbe09c11f..fc080f64b9c87a0b9784dceb75dc3ec97abe9596 100644 (file)
@@ -110,8 +110,13 @@ class ChatBuffer
        void scrollAbsolute(s32 scroll);
        // Scroll to bottom of buffer (newest)
        void scrollBottom();
-       // Scroll to top of buffer (oldest)
-       void scrollTop();
+
+       // Functions for keeping track of whether the lines were modified by any
+       // preceding operations
+       // If they were not changed, getLineCount() and getLine() output the same as
+       // before
+       bool getLinesModified() const { return m_lines_modified; }
+       void resetLinesModified() { m_lines_modified = false; }
 
        // Format a chat line for the given number of columns.
        // Appends the formatted lines to the destination array and
@@ -146,6 +151,11 @@ class ChatBuffer
        bool m_cache_clickable_chat_weblinks;
        // Color of clickable chat weblinks
        irr::video::SColor m_cache_chat_weblink_color;
+
+       // Whether the lines were modified since last markLinesUnchanged()
+       // Is always set to true when m_unformatted is modified, because that's what
+       // determines the output of getLineCount() and getLine()
+       bool m_lines_modified = true;
 };
 
 class ChatPrompt
index 8d058852a90ca758781815e2b908a6fc966174b6..656ad45cebf01a773afaea4943b00571cb8eb2b0 100644 (file)
@@ -60,7 +60,7 @@ set(client_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/wieldmesh.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/shadows/dynamicshadows.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/shadows/dynamicshadowsrender.cpp
-       ${CMAKE_CURRENT_SOURCE_DIR}/shadows/shadowsshadercallbacks.cpp  
-       ${CMAKE_CURRENT_SOURCE_DIR}/shadows/shadowsScreenQuad.cpp       
+       ${CMAKE_CURRENT_SOURCE_DIR}/shadows/shadowsshadercallbacks.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/shadows/shadowsScreenQuad.cpp
        PARENT_SCOPE
 )
index 52bedcba93979291c00adf43eafaafb7a80cfccf..0c387262ebe039df92473875de58b4136a196e54 100644 (file)
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "player.h"
 #include <cmath>
 #include "client/renderingengine.h"
+#include "client/content_cao.h"
 #include "settings.h"
 #include "wieldmesh.h"
 #include "noise.h"         // easeCurve
@@ -37,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "fontengine.h"
 #include "guiscalingfilter.h"
 #include "script/scripting_client.h"
+#include "gettext.h"
 
 #define CAMERA_OFFSET_STEP 200
 #define WIELDMESH_OFFSET_X 55.0f
@@ -133,28 +135,6 @@ void Camera::notifyFovChange()
        }
 }
 
-bool Camera::successfullyCreated(std::string &error_message)
-{
-       if (!m_playernode) {
-               error_message = "Failed to create the player scene node";
-       } else if (!m_headnode) {
-               error_message = "Failed to create the head scene node";
-       } else if (!m_cameranode) {
-               error_message = "Failed to create the camera scene node";
-       } else if (!m_wieldmgr) {
-               error_message = "Failed to create the wielded item scene manager";
-       } else if (!m_wieldnode) {
-               error_message = "Failed to create the wielded item scene node";
-       } else {
-               error_message.clear();
-       }
-
-       if (m_client->modsLoaded())
-               m_client->getScript()->on_camera_ready(this);
-
-       return error_message.empty();
-}
-
 // Returns the fractional part of x
 inline f32 my_modf(f32 x)
 {
@@ -187,9 +167,7 @@ void Camera::step(f32 dtime)
                                m_view_bobbing_anim -= offset;
                        } else if (m_view_bobbing_anim > 0.75) {
                                m_view_bobbing_anim += offset;
-                       }
-
-                       if (m_view_bobbing_anim < 0.5) {
+                       } else if (m_view_bobbing_anim < 0.5) {
                                m_view_bobbing_anim += offset;
                                if (m_view_bobbing_anim > 0.5)
                                        m_view_bobbing_anim = 0.5;
@@ -331,7 +309,7 @@ void Camera::addArmInertia(f32 player_yaw)
        }
 }
 
-void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_reload_ratio)
+void Camera::update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio)
 {
        // Get player position
        // Smooth the movement when walking up stairs
@@ -344,13 +322,16 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r
        if (player->getParent())
                player_position = player->getParent()->getPosition() + v3f(0,  g_settings->getBool("float_above_parent") ? BS : 0, 0);
 
-       // Smooth the camera movement when the player instantly moves upward due to stepheight.
-       // To smooth the 'not touching_ground' stepheight, smoothing is necessary when jumping
-       // or swimming (for when moving from liquid to land).
-       // Disable smoothing if climbing or flying, to avoid upwards offset of player model
-       // when seen in 3rd person view.
-       bool flying = (g_settings->getBool("free_move") && m_client->checkLocalPrivilege("fly")) || g_settings->getBool("freecam");
-       if (player_position.Y > old_player_position.Y && !player->is_climbing && !flying) {
+       // Smooth the camera movement after the player instantly moves upward due to stepheight.
+       // The smoothing usually continues until the camera position reaches the player position.
+       float player_stepheight = player->getCAO() ? player->getCAO()->getStepHeight() : HUGE_VALF;
+       float upward_movement = player_position.Y - old_player_position.Y;
+       if (upward_movement < 0.01f || upward_movement > player_stepheight) {
+               m_stepheight_smooth_active = false;
+       } else if (player->touching_ground) {
+               m_stepheight_smooth_active = true;
+       }
+       if (m_stepheight_smooth_active) {
                f32 oldy = old_player_position.Y;
                f32 newy = player_position.Y;
                f32 t = std::exp(-23 * frametime);
@@ -379,7 +360,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r
                // Smoothen and invert the above
                fall_bobbing = sin(fall_bobbing * 0.5 * M_PI) * -1;
                // Amplify according to the intensity of the impact
-               fall_bobbing *= (1 - rangelim(50 / player->camera_impact, 0, 1)) * 5;
+               if (player->camera_impact > 0.0f)
+                       fall_bobbing *= (1 - rangelim(50 / player->camera_impact, 0, 1)) * 5;
 
                fall_bobbing *= m_cache_fall_bobbing_amount;
        }
@@ -410,41 +392,17 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r
                f32 bobfrac = my_modf(m_view_bobbing_anim * 2);
                f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0;
 
-               #if 1
                f32 bobknob = 1.2;
                f32 bobtmp = sin(pow(bobfrac, bobknob) * M_PI);
-               //f32 bobtmp2 = cos(pow(bobfrac, bobknob) * M_PI);
 
                v3f bobvec = v3f(
                        0.3 * bobdir * sin(bobfrac * M_PI),
                        -0.28 * bobtmp * bobtmp,
                        0.);
 
-               //rel_cam_pos += 0.2 * bobvec;
-               //rel_cam_target += 0.03 * bobvec;
-               //rel_cam_up.rotateXYBy(0.02 * bobdir * bobtmp * M_PI);
-               float f = 1.0;
-               f *= m_cache_view_bobbing_amount;
-               rel_cam_pos += bobvec * f;
-               //rel_cam_target += 0.995 * bobvec * f;
-               rel_cam_target += bobvec * f;
-               rel_cam_target.Z -= 0.005 * bobvec.Z * f;
-               //rel_cam_target.X -= 0.005 * bobvec.X * f;
-               //rel_cam_target.Y -= 0.005 * bobvec.Y * f;
-               rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * M_PI * f);
-               #else
-               f32 angle_deg = 1 * bobdir * sin(bobfrac * M_PI);
-               f32 angle_rad = angle_deg * M_PI / 180;
-               f32 r = 0.05;
-               v3f off = v3f(
-                       r * sin(angle_rad),
-                       r * (cos(angle_rad) - 1),
-                       0);
-               rel_cam_pos += off;
-               //rel_cam_target += off;
-               rel_cam_up.rotateXYBy(angle_deg);
-               #endif
-
+               rel_cam_pos += bobvec * m_cache_view_bobbing_amount;
+               rel_cam_target += bobvec * m_cache_view_bobbing_amount;
+               rel_cam_up.rotateXYBy(-0.03 * bobdir * bobtmp * M_PI * m_cache_view_bobbing_amount);
        }
 
        // Compute absolute camera position and target
@@ -613,6 +571,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r
        const bool walking = movement_XZ && player->touching_ground;
        const bool swimming = (movement_XZ || player->swimming_vertical) && player->in_liquid;
        const bool climbing = movement_Y && player->is_climbing;
+       const bool flying = g_settings->getBool("free_move")
+               && m_client->checkLocalPrivilege("fly");
        if ((walking || swimming || climbing) && !flying) {
                // Start animation
                m_view_bobbing_state = 1;
index 30fac52899a0d8bdd60cfe3acf68e1dcdaad0d67..ecd71f1e72d2cee62f6956d84b0cc4d2690cd675 100644 (file)
@@ -162,16 +162,11 @@ class Camera
        // Notify about new server-sent FOV and initialize smooth FOV transition
        void notifyFovChange();
 
-       // Checks if the constructor was able to create the scene nodes
-       bool successfullyCreated(std::string &error_message);
-
        // Step the camera: updates the viewing range and view bobbing.
        void step(f32 dtime);
 
        // Update the camera from the local player's position.
-       // busytime is used to adjust the viewing range.
-       void update(LocalPlayer* player, f32 frametime, f32 busytime,
-                       f32 tool_reload_ratio);
+       void update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio);
 
        // Update render distance
        void updateViewingRange();
@@ -245,6 +240,8 @@ class Camera
        // Camera offset
        v3s16 m_camera_offset;
 
+       bool m_stepheight_smooth_active = false;
+
        // Server-sent FOV variables
        bool m_server_sent_fov = false;
        f32 m_curr_fov_degrees, m_old_fov_degrees, m_target_fov_degrees;
index 3c4ea5f95f6a2be6d2407f581db91d6fa54458ab..4e4bb8a97ea8afbe6ecf4ac7a18bba51887b4cc3 100644 (file)
@@ -51,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "clientmap.h"
 #include "clientmedia.h"
 #include "version.h"
+#include "database/database-files.h"
 #include "database/database-sqlite3.h"
 #include "serialization.h"
 #include "guiscalingfilter.h"
@@ -129,6 +130,11 @@ Client::Client(
        // Add local player
        m_env.setLocalPlayer(new LocalPlayer(this, playername));
 
+       // Make the mod storage database and begin the save for later
+       m_mod_storage_database =
+               new ModMetadataDatabaseSQLite3(porting::path_user + DIR_DELIM + "client");
+       m_mod_storage_database->beginSave();
+
        if (g_settings->getBool("enable_minimap")) {
                m_minimap = new Minimap(this);
        }
@@ -136,6 +142,33 @@ Client::Client(
        m_cache_save_interval = g_settings->getU16("server_map_save_interval");
 }
 
+void Client::migrateModStorage()
+{
+       std::string mod_storage_dir = porting::path_user + DIR_DELIM + "client";
+       std::string old_mod_storage = mod_storage_dir + DIR_DELIM + "mod_storage";
+       if (fs::IsDir(old_mod_storage)) {
+               infostream << "Migrating client mod storage to SQLite3 database" << std::endl;
+               {
+                       ModMetadataDatabaseFiles files_db(mod_storage_dir);
+                       std::vector<std::string> mod_list;
+                       files_db.listMods(&mod_list);
+                       for (const std::string &modname : mod_list) {
+                               infostream << "Migrating client mod storage for mod " << modname << std::endl;
+                               StringMap meta;
+                               files_db.getModEntries(modname, &meta);
+                               for (const auto &pair : meta) {
+                                       m_mod_storage_database->setModEntry(modname, pair.first, pair.second);
+                               }
+                       }
+               }
+               if (!fs::Rename(old_mod_storage, old_mod_storage + ".bak")) {
+                       // Execution cannot move forward if the migration does not complete.
+                       throw BaseException("Could not finish migrating client mod storage");
+               }
+               infostream << "Finished migration of client mod storage" << std::endl;
+       }
+}
+
 void Client::loadMods()
 {
        // Don't load mods twice.
@@ -304,10 +337,17 @@ Client::~Client()
        // cleanup 3d model meshes on client shutdown
        m_rendering_engine->cleanupMeshCache();
 
+       guiScalingCacheClear();
+
        delete m_minimap;
        m_minimap = nullptr;
 
        delete m_media_downloader;
+
+       // Write the changes and delete
+       if (m_mod_storage_database)
+               m_mod_storage_database->endSave();
+       delete m_mod_storage_database;
 }
 
 void Client::connect(Address address, bool is_local_server)
@@ -644,19 +684,12 @@ void Client::step(float dtime)
                }
        }
 
+       // Write changes to the mod storage
        m_mod_storage_save_timer -= dtime;
        if (m_mod_storage_save_timer <= 0.0f) {
                m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
-               int n = 0;
-               for (std::unordered_map<std::string, ModMetadata *>::const_iterator
-                               it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
-                       if (it->second->isModified()) {
-                               it->second->save(getModStoragePath());
-                               n++;
-                       }
-               }
-               if (n > 0)
-                       infostream << "Saved " << n << " modified mod storages." << std::endl;
+               m_mod_storage_database->endSave();
+               m_mod_storage_database->beginSave();
        }
 
        // Write server map
@@ -880,7 +913,7 @@ void Client::ProcessData(NetworkPacket *pkt)
        */
        if(sender_peer_id != PEER_ID_SERVER) {
                infostream << "Client::ProcessData(): Discarding data not "
-                       "coming from server: peer_id=" << sender_peer_id
+                       "coming from server: peer_id=" << sender_peer_id << " command=" << pkt->getCommand()
                        << std::endl;
                return;
        }
@@ -931,7 +964,7 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *
        v3f sf           = myplayer->getSendSpeed() * 100;
        s32 pitch        = myplayer->getPitch() * 100;
        s32 yaw          = myplayer->getYaw() * 100;
-       u32 keyPressed   = myplayer->keyPressed;
+       u32 keyPressed   = myplayer->control.getKeysPressed();
        // scaled by 80, so that pi can fit into a u8
        u8 fov           = clientMap->getCameraFov() * 80;
        u8 wanted_range  = MYMIN(255,
@@ -1287,22 +1320,24 @@ void Client::sendPlayerPos(v3f pos)
        if (!player)
                return;
 
-       ClientMap &map = m_env.getClientMap();
-       u8 camera_fov   = map.getCameraFov();
-       u8 wanted_range = map.getControl().wanted_range;
-
        // Save bandwidth by only updating position when
        // player is not dead and something changed
 
        if (m_activeobjects_received && player->isDead())
                return;
 
+       ClientMap &map = m_env.getClientMap();
+       u8 camera_fov   = map.getCameraFov();
+       u8 wanted_range = map.getControl().wanted_range;
+
+       u32 keyPressed = player->control.getKeysPressed();
+
        if (
                        player->last_position     == pos &&
                        player->last_speed        == player->getSendSpeed()    &&
                        player->last_pitch        == player->getPitch()    &&
                        player->last_yaw          == player->getYaw()      &&
-                       player->last_keyPressed   == player->keyPressed    &&
+                       player->last_keyPressed   == keyPressed            &&
                        player->last_camera_fov   == camera_fov            &&
                        player->last_wanted_range == wanted_range)
                return;
@@ -1311,7 +1346,7 @@ void Client::sendPlayerPos(v3f pos)
        player->last_speed        = player->getSendSpeed();
        player->last_pitch        = player->getPitch();
        player->last_yaw          = player->getYaw();
-       player->last_keyPressed   = player->keyPressed;
+       player->last_keyPressed   = keyPressed;
        player->last_camera_fov   = camera_fov;
        player->last_wanted_range = wanted_range;
 
@@ -1614,20 +1649,7 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent)
 
 void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool urgent)
 {
-       try{
-               addUpdateMeshTask(blockpos, ack_to_server, urgent);
-       }
-       catch(InvalidPositionException &e){}
-
-       // Leading edge
-       for (int i=0;i<6;i++)
-       {
-               try{
-                       v3s16 p = blockpos + g_6dirs[i];
-                       addUpdateMeshTask(p, false, urgent);
-               }
-               catch(InvalidPositionException &e){}
-       }
+       m_mesh_update_thread.updateBlock(&m_env.getMap(), blockpos, ack_to_server, urgent, true);
 }
 
 void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool urgent)
@@ -1639,38 +1661,16 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur
                                <<std::endl;
        }
 
-       v3s16 blockpos          = getNodeBlockPos(nodepos);
+       v3s16 blockpos = getNodeBlockPos(nodepos);
        v3s16 blockpos_relative = blockpos * MAP_BLOCKSIZE;
-
-       try{
-               addUpdateMeshTask(blockpos, ack_to_server, urgent);
-       }
-       catch(InvalidPositionException &e) {}
-
+       m_mesh_update_thread.updateBlock(&m_env.getMap(), blockpos, ack_to_server, urgent, false);
        // Leading edge
-       if(nodepos.X == blockpos_relative.X){
-               try{
-                       v3s16 p = blockpos + v3s16(-1,0,0);
-                       addUpdateMeshTask(p, false, urgent);
-               }
-               catch(InvalidPositionException &e){}
-       }
-
-       if(nodepos.Y == blockpos_relative.Y){
-               try{
-                       v3s16 p = blockpos + v3s16(0,-1,0);
-                       addUpdateMeshTask(p, false, urgent);
-               }
-               catch(InvalidPositionException &e){}
-       }
-
-       if(nodepos.Z == blockpos_relative.Z){
-               try{
-                       v3s16 p = blockpos + v3s16(0,0,-1);
-                       addUpdateMeshTask(p, false, urgent);
-               }
-               catch(InvalidPositionException &e){}
-       }
+       if (nodepos.X == blockpos_relative.X)
+               addUpdateMeshTask(blockpos + v3s16(-1, 0, 0), false, urgent);
+       if (nodepos.Y == blockpos_relative.Y)
+               addUpdateMeshTask(blockpos + v3s16(0, -1, 0), false, urgent);
+       if (nodepos.Z == blockpos_relative.Z)
+               addUpdateMeshTask(blockpos + v3s16(0, 0, -1), false, urgent);
 }
 
 void Client::updateAllMapBlocks()
@@ -1834,11 +1834,10 @@ void Client::makeScreenshot()
        if (!raw_image)
                return;
 
-       time_t t = time(NULL);
-       struct tm *tm = localtime(&t);
+       const struct tm tm = mt_localtime();
 
        char timetstamp_c[64];
-       strftime(timetstamp_c, sizeof(timetstamp_c), "%Y%m%d_%H%M%S", tm);
+       strftime(timetstamp_c, sizeof(timetstamp_c), "%Y%m%d_%H%M%S", &tm);
 
        std::string screenshot_dir;
 
@@ -2025,16 +2024,8 @@ void Client::unregisterModStorage(const std::string &name)
 {
        std::unordered_map<std::string, ModMetadata *>::const_iterator it =
                m_mod_storages.find(name);
-       if (it != m_mod_storages.end()) {
-               // Save unconditionaly on unregistration
-               it->second->save(getModStoragePath());
+       if (it != m_mod_storages.end())
                m_mod_storages.erase(name);
-       }
-}
-
-std::string Client::getModStoragePath() const
-{
-       return porting::path_user + DIR_DELIM + "client" + DIR_DELIM + "mod_storage";
 }
 
 /*
index 1493d3ce3eecd959ce7a5696ca85bdad7fea7af7..d49f2f9ada7392fe9426da50f89c05ba6c838d87 100644 (file)
@@ -226,6 +226,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
        void handleCommand_PlayerSpeed(NetworkPacket *pkt);
        void handleCommand_MediaPush(NetworkPacket *pkt);
        void handleCommand_MinimapModes(NetworkPacket *pkt);
+       void handleCommand_SetLighting(NetworkPacket *pkt);
 
        void ProcessData(NetworkPacket *pkt);
 
@@ -335,13 +336,13 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
        // disconnect client when CSM failed.
        const std::string &accessDeniedReason() const { return m_access_denied_reason; }
 
-       const bool itemdefReceived() const
+       bool itemdefReceived() const
        { return m_itemdef_received; }
-       const bool nodedefReceived() const
+       bool nodedefReceived() const
        { return m_nodedef_received; }
-       const bool mediaReceived() const
+       bool mediaReceived() const
        { return !m_media_downloader; }
-       const bool activeObjectsReceived() const
+       bool activeObjectsReceived() const
        { return m_activeobjects_received; }
 
        u16 getProtoVersion()
@@ -382,11 +383,14 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
        bool checkLocalPrivilege(const std::string &priv){ return checkPrivilege(priv); }
        virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
        const std::string* getModFile(std::string filename);
+       ModMetadataDatabase *getModStorageDatabase() override { return m_mod_storage_database; }
 
-       std::string getModStoragePath() const override;
        bool registerModStorage(ModMetadata *meta) override;
        void unregisterModStorage(const std::string &name) override;
 
+       // Migrates away old files-based mod storage if necessary
+       void migrateModStorage();
+
        // The following set of functions is used by ClientMediaDownloader
        // Insert a media file appropriately into the appropriate manager
        bool loadMedia(const std::string &data, const std::string &filename,
@@ -405,7 +409,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
        }
 
        ClientScripting *getScript() { return m_script; }
-       const bool modsLoaded() const { return m_mods_loaded; }
+       bool modsLoaded() const { return m_mods_loaded; }
 
        void pushToEventQueue(ClientEvent *event);
 
@@ -554,7 +558,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
        // Set of media filenames pushed by server at runtime
        std::unordered_set<std::string> m_media_pushed_files;
        // Pending downloads of dynamic media (key: token)
-       std::vector<std::pair<u32, std::unique_ptr<SingleMediaDownloader>>> m_pending_media_downloads;
+       std::vector<std::pair<u32, std::shared_ptr<SingleMediaDownloader>>> m_pending_media_downloads;
 
        // time_of_day speed approximation for old protocol
        bool m_time_of_day_set = false;
@@ -596,6 +600,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
        // Client modding
        ClientScripting *m_script = nullptr;
        std::unordered_map<std::string, ModMetadata *> m_mod_storages;
+       ModMetadataDatabase *m_mod_storage_database = nullptr;
        float m_mod_storage_save_timer = 10.0f;
        std::vector<ModSpec> m_mods;
        StringMap m_mod_vfs;
index f9c20b2dffad5f6226f870116a898ddfb565290e..01aaa0408c4767307d426e82bbedb2c8d06d3f21 100644 (file)
@@ -193,33 +193,41 @@ void ClientEnvironment::step(float dtime)
                // Control local player
                lplayer->applyControl(dtime_part, this);
 
-               // Apply physics
-               if (!free_move && !is_climbing && !g_settings->getBool("freecam")) {
+               if (!free_move && !g_settings->getBool("freecam")) {
                        // Gravity
                        v3f speed = lplayer->getSpeed();
-                       if (!lplayer->in_liquid)
+                       if (!is_climbing && !lplayer->in_liquid)
                                speed.Y -= lplayer->movement_gravity *
                                        lplayer->physics_override_gravity * dtime_part * 2.0f;
 
                        // Liquid floating / sinking
-                       if (lplayer->in_liquid && !lplayer->swimming_vertical &&
+                       if (!is_climbing && lplayer->in_liquid &&
+                                       !lplayer->swimming_vertical &&
                                        !lplayer->swimming_pitch)
                                speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f;
 
-                       // Liquid resistance
-                       if (lplayer->in_liquid_stable || lplayer->in_liquid) {
-                               // How much the node's viscosity blocks movement, ranges
-                               // between 0 and 1. Should match the scale at which viscosity
+                       // Movement resistance
+                       if (lplayer->move_resistance > 0) {
+                               // How much the node's move_resistance blocks movement, ranges
+                               // between 0 and 1. Should match the scale at which liquid_viscosity
                                // increase affects other liquid attributes.
-                               static const f32 viscosity_factor = 0.3f;
-
-                               v3f d_wanted = -speed / lplayer->movement_liquid_fluidity;
+                               static const f32 resistance_factor = 0.3f;
+
+                               v3f d_wanted;
+                               bool in_liquid_stable = lplayer->in_liquid_stable || lplayer->in_liquid;
+                               if (in_liquid_stable) {
+                                       d_wanted = -speed / lplayer->movement_liquid_fluidity;
+                               } else {
+                                       d_wanted = -speed / BS;
+                               }
                                f32 dl = d_wanted.getLength();
-                               if (dl > lplayer->movement_liquid_fluidity_smooth)
-                                       dl = lplayer->movement_liquid_fluidity_smooth;
+                               if (in_liquid_stable) {
+                                       if (dl > lplayer->movement_liquid_fluidity_smooth)
+                                               dl = lplayer->movement_liquid_fluidity_smooth;
+                               }
 
-                               dl *= (lplayer->liquid_viscosity * viscosity_factor) +
-                                       (1 - viscosity_factor);
+                               dl *= (lplayer->move_resistance * resistance_factor) +
+                                       (1 - resistance_factor);
                                v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f);
                                speed += d;
                        }
index 6ab6106702fcb116fb6a464c96be20c8527e1d50..54c561d11ecccfe738ec50b0764cfb6dbaf6b395 100644 (file)
@@ -38,9 +38,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #if USE_SOUND
        #include "sound_openal.h"
 #endif
-#ifdef __ANDROID__
-       #include "porting.h"
-#endif
 
 /* mainmenumanager.h
  */
@@ -73,10 +70,10 @@ static void dump_start_data(const GameStartData &data)
 
 ClientLauncher::~ClientLauncher()
 {
-       delete receiver;
-
        delete input;
 
+       delete receiver;
+
        delete g_fontengine;
        delete g_gamecallback;
 
@@ -147,8 +144,8 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
        skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
        skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50));
        skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));
-#ifdef __ANDROID__
-       float density = porting::getDisplayDensity();
+#ifdef HAVE_TOUCHSCREENGUI
+       float density = RenderingEngine::getDisplayDensity();
        skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density));
        skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density));
        skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density));
@@ -567,6 +564,8 @@ void ClientLauncher::speed_tests()
        // volatile to avoid some potential compiler optimisations
        volatile static s16 temp16;
        volatile static f32 tempf;
+       // Silence compiler warning
+       (void)temp16;
        static v3f tempv3f1;
        static v3f tempv3f2;
        static std::string tempstring;
index 4a4784f91b13e575c1b6aef9299fcc0d0cec6113..51f0f6896774dc10a64cb622c0b5499f492a5586 100644 (file)
@@ -73,7 +73,8 @@ ClientMap::ClientMap(
                rendering_engine->get_scene_manager(), id),
        m_client(client),
        m_rendering_engine(rendering_engine),
-       m_control(control)
+       m_control(control),
+       m_drawlist(MapBlockComparer(v3s16(0,0,0)))
 {
 
        /*
@@ -96,9 +97,32 @@ ClientMap::ClientMap(
        m_cache_trilinear_filter  = g_settings->getBool("trilinear_filter");
        m_cache_bilinear_filter   = g_settings->getBool("bilinear_filter");
        m_cache_anistropic_filter = g_settings->getBool("anisotropic_filter");
+       m_cache_transparency_sorting_distance = g_settings->getU16("transparency_sorting_distance");
 
 }
 
+void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset)
+{
+       v3s16 previous_node = floatToInt(m_camera_position, BS) + m_camera_offset;
+       v3s16 previous_block = getContainerPos(previous_node, MAP_BLOCKSIZE);
+
+       m_camera_position = pos;
+       m_camera_direction = dir;
+       m_camera_fov = fov;
+       m_camera_offset = offset;
+
+       v3s16 current_node = floatToInt(m_camera_position, BS) + m_camera_offset;
+       v3s16 current_block = getContainerPos(current_node, MAP_BLOCKSIZE);
+
+       // reorder the blocks when camera crosses block boundary
+       if (previous_block != current_block)
+               m_needs_update_drawlist = true;
+
+       // reorder transparent meshes when camera crosses node boundary
+       if (previous_node != current_node)
+               m_needs_update_transparent_meshes = true;
+}
+
 MapSector * ClientMap::emergeSector(v2s16 p2d)
 {
        // Check that it doesn't exist already
@@ -164,6 +188,8 @@ void ClientMap::updateDrawList()
 {
        ScopeProfiler sp(g_profiler, "CM::updateDrawList()", SPT_AVG);
 
+       m_needs_update_drawlist = false;
+
        for (auto &i : m_drawlist) {
                MapBlock *block = i.second;
                block->refDrop();
@@ -178,6 +204,7 @@ void ClientMap::updateDrawList()
        const f32 camera_fov = m_camera_fov * 1.1f;
 
        v3s16 cam_pos_nodes = floatToInt(camera_position, BS);
+
        v3s16 p_blocks_min;
        v3s16 p_blocks_max;
        getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
@@ -202,6 +229,8 @@ void ClientMap::updateDrawList()
                        occlusion_culling_enabled = false;
        }
 
+       v3s16 camera_block = getContainerPos(cam_pos_nodes, MAP_BLOCKSIZE);
+       m_drawlist = std::map<v3s16, MapBlock*, MapBlockComparer>(MapBlockComparer(camera_block));
 
        // Uncomment to debug occluded blocks in the wireframe mode
        // TODO: Include this as a flag for an extended debugging setting
@@ -317,11 +346,19 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
        u32 mesh_animate_count = 0;
        //u32 mesh_animate_count_far = 0;
 
+       /*
+               Update transparent meshes
+       */
+       if (is_transparent_pass)
+               updateTransparentMeshBuffers();
+
        /*
                Draw the selected MapBlocks
        */
 
-       MeshBufListList drawbufs;
+       MeshBufListList grouped_buffers;
+       std::vector<DrawDescriptor> draw_order;
+       video::SMaterial previous_material;
 
        for (auto &i : m_drawlist) {
                v3s16 block_pos = i.first;
@@ -356,7 +393,15 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                /*
                        Get the meshbuffers of the block
                */
-               {
+               if (is_transparent_pass) {
+                       // In transparent pass, the mesh will give us
+                       // the partial buffers in the correct order
+                       for (auto &buffer : block->mesh->getTransparentBuffers())
+                               draw_order.emplace_back(block_pos, &buffer);
+               }
+               else {
+                       // otherwise, group buffers across meshes
+                       // using MeshBufListList
                        MapBlockMesh *mapBlockMesh = block->mesh;
                        assert(mapBlockMesh);
 
@@ -370,69 +415,94 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
 
                                        video::SMaterial& material = buf->getMaterial();
                                        video::IMaterialRenderer* rnd =
-                                               driver->getMaterialRenderer(material.MaterialType);
+                                                       driver->getMaterialRenderer(material.MaterialType);
                                        bool transparent = (rnd && rnd->isTransparent());
-                                       if (transparent == is_transparent_pass) {
+                                       if (!transparent) {
                                                if (buf->getVertexCount() == 0)
                                                        errorstream << "Block [" << analyze_block(block)
-                                                               << "] contains an empty meshbuf" << std::endl;
-
-                                               material.setFlag(video::EMF_TRILINEAR_FILTER,
-                                                       m_cache_trilinear_filter);
-                                               material.setFlag(video::EMF_BILINEAR_FILTER,
-                                                       m_cache_bilinear_filter);
-                                               material.setFlag(video::EMF_ANISOTROPIC_FILTER,
-                                                       m_cache_anistropic_filter);
-                                               material.setFlag(video::EMF_WIREFRAME,
-                                                       m_control.show_wireframe);
-
-                                               drawbufs.add(buf, block_pos, layer);
+                                                                       << "] contains an empty meshbuf" << std::endl;
+
+                                               grouped_buffers.add(buf, block_pos, layer);
                                        }
                                }
                        }
                }
        }
 
+       // Capture draw order for all solid meshes
+       for (auto &lists : grouped_buffers.lists) {
+               for (MeshBufList &list : lists) {
+                       // iterate in reverse to draw closest blocks first
+                       for (auto it = list.bufs.rbegin(); it != list.bufs.rend(); ++it) {
+                               draw_order.emplace_back(it->first, it->second, it != list.bufs.rbegin());
+                       }
+               }
+       }
+
        TimeTaker draw("Drawing mesh buffers");
 
        core::matrix4 m; // Model matrix
        v3f offset = intToFloat(m_camera_offset, BS);
+       u32 material_swaps = 0;
 
-       // Render all layers in order
-       for (auto &lists : drawbufs.lists) {
-               for (MeshBufList &list : lists) {
-                       // Check and abort if the machine is swapping a lot
-                       if (draw.getTimerTime() > 2000) {
-                               infostream << "ClientMap::renderMap(): Rendering took >2s, " <<
-                                               "returning." << std::endl;
-                               return;
-                       }
+       // Render all mesh buffers in order
+       drawcall_count += draw_order.size();
+
+       for (auto &descriptor : draw_order) {
+               scene::IMeshBuffer *buf;
+               
+               if (descriptor.m_use_partial_buffer) {
+                       descriptor.m_partial_buffer->beforeDraw();
+                       buf = descriptor.m_partial_buffer->getBuffer();
+               }
+               else {
+                       buf = descriptor.m_buffer;
+               }
+
+               // Check and abort if the machine is swapping a lot
+               if (draw.getTimerTime() > 2000) {
+                       infostream << "ClientMap::renderMap(): Rendering took >2s, " <<
+                                       "returning." << std::endl;
+                       return;
+               }
+
+               if (!descriptor.m_reuse_material) {
+                       auto &material = buf->getMaterial();
+
+                       // Apply filter settings
+                       material.setFlag(video::EMF_TRILINEAR_FILTER,
+                               m_cache_trilinear_filter);
+                       material.setFlag(video::EMF_BILINEAR_FILTER,
+                               m_cache_bilinear_filter);
+                       material.setFlag(video::EMF_ANISOTROPIC_FILTER,
+                               m_cache_anistropic_filter);
+                       material.setFlag(video::EMF_WIREFRAME,
+                               m_control.show_wireframe);
 
                        // pass the shadow map texture to the buffer texture
                        ShadowRenderer *shadow = m_rendering_engine->get_shadow_renderer();
                        if (shadow && shadow->is_active()) {
-                               auto &layer = list.m.TextureLayer[3];
+                               auto &layer = material.TextureLayer[3];
                                layer.Texture = shadow->get_texture();
                                layer.TextureWrapU = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
                                layer.TextureWrapV = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
-                               layer.TrilinearFilter = true;
+                               // Do not enable filter on shadow texture to avoid visual artifacts
+                               // with colored shadows.
+                               // Filtering is done in shader code anyway
+                               layer.TrilinearFilter = false;
                        }
+                       driver->setMaterial(material);
+                       ++material_swaps;
+               }
 
-                       driver->setMaterial(list.m);
-
-                       drawcall_count += list.bufs.size();
-                       for (auto &pair : list.bufs) {
-                               scene::IMeshBuffer *buf = pair.second;
-
-                               v3f block_wpos = intToFloat(pair.first * MAP_BLOCKSIZE, BS);
-                               m.setTranslation(block_wpos - offset);
+               v3f block_wpos = intToFloat(descriptor.m_pos * MAP_BLOCKSIZE, BS);
+               m.setTranslation(block_wpos - offset);
 
-                               driver->setTransform(video::ETS_WORLD, m);
-                               driver->drawMeshBuffer(buf);
-                               vertex_count += buf->getVertexCount();
-                       }
-               }
+               driver->setTransform(video::ETS_WORLD, m);
+               driver->drawMeshBuffer(buf);
+               vertex_count += buf->getIndexCount();
        }
+
        g_profiler->avg(prefix + "draw meshes [ms]", draw.stop(true));
 
        // Log only on solid pass because values are the same
@@ -440,8 +510,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                g_profiler->avg("renderMap(): animated meshes [#]", mesh_animate_count);
        }
 
+       if (pass == scene::ESNRP_TRANSPARENT) {
+               g_profiler->avg("renderMap(): transparent buffers [#]", draw_order.size());
+       }
+
        g_profiler->avg(prefix + "vertices drawn [#]", vertex_count);
        g_profiler->avg(prefix + "drawcalls [#]", drawcall_count);
+       g_profiler->avg(prefix + "material swaps [#]", material_swaps);
 }
 
 static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,
@@ -648,7 +723,9 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
        u32 drawcall_count = 0;
        u32 vertex_count = 0;
 
-       MeshBufListList drawbufs;
+       MeshBufListList grouped_buffers;
+       std::vector<DrawDescriptor> draw_order;
+
 
        int count = 0;
        int low_bound = is_transparent_pass ? 0 : m_drawlist_shadow.size() / total_frames * frame;
@@ -677,7 +754,15 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
                /*
                        Get the meshbuffers of the block
                */
-               {
+               if (is_transparent_pass) {
+                       // In transparent pass, the mesh will give us
+                       // the partial buffers in the correct order
+                       for (auto &buffer : block->mesh->getTransparentBuffers())
+                               draw_order.emplace_back(block_pos, &buffer);
+               }
+               else {
+                       // otherwise, group buffers across meshes
+                       // using MeshBufListList
                        MapBlockMesh *mapBlockMesh = block->mesh;
                        assert(mapBlockMesh);
 
@@ -692,79 +777,99 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
                                        video::SMaterial &mat = buf->getMaterial();
                                        auto rnd = driver->getMaterialRenderer(mat.MaterialType);
                                        bool transparent = rnd && rnd->isTransparent();
-                                       if (transparent == is_transparent_pass)
-                                               drawbufs.add(buf, block_pos, layer);
+                                       if (!transparent)
+                                               grouped_buffers.add(buf, block_pos, layer);
                                }
                        }
                }
        }
 
+       u32 buffer_count = 0;
+       for (auto &lists : grouped_buffers.lists)
+               for (MeshBufList &list : lists)
+                       buffer_count += list.bufs.size();
+       
+       draw_order.reserve(draw_order.size() + buffer_count);
+       
+       // Capture draw order for all solid meshes
+       for (auto &lists : grouped_buffers.lists) {
+               for (MeshBufList &list : lists) {
+                       // iterate in reverse to draw closest blocks first
+                       for (auto it = list.bufs.rbegin(); it != list.bufs.rend(); ++it)
+                               draw_order.emplace_back(it->first, it->second, it != list.bufs.rbegin());
+               }
+       }
+
        TimeTaker draw("Drawing shadow mesh buffers");
 
        core::matrix4 m; // Model matrix
        v3f offset = intToFloat(m_camera_offset, BS);
+       u32 material_swaps = 0;
 
-       // Render all layers in order
-       for (auto &lists : drawbufs.lists) {
-               for (MeshBufList &list : lists) {
-                       // Check and abort if the machine is swapping a lot
-                       if (draw.getTimerTime() > 1000) {
-                               infostream << "ClientMap::renderMapShadows(): Rendering "
-                                               "took >1s, returning." << std::endl;
-                               break;
-                       }
-                       for (auto &pair : list.bufs) {
-                               scene::IMeshBuffer *buf = pair.second;
-
-                               // override some material properties
-                               video::SMaterial local_material = buf->getMaterial();
-                               local_material.MaterialType = material.MaterialType;
-                               local_material.BackfaceCulling = material.BackfaceCulling;
-                               local_material.FrontfaceCulling = material.FrontfaceCulling;
-                               local_material.BlendOperation = material.BlendOperation;
-                               local_material.Lighting = false;
-                               driver->setMaterial(local_material);
-
-                               v3f block_wpos = intToFloat(pair.first * MAP_BLOCKSIZE, BS);
-                               m.setTranslation(block_wpos - offset);
-
-                               driver->setTransform(video::ETS_WORLD, m);
-                               driver->drawMeshBuffer(buf);
-                               vertex_count += buf->getVertexCount();
-                       }
+       // Render all mesh buffers in order
+       drawcall_count += draw_order.size();
+
+       for (auto &descriptor : draw_order) {
+               scene::IMeshBuffer *buf;
+               
+               if (descriptor.m_use_partial_buffer) {
+                       descriptor.m_partial_buffer->beforeDraw();
+                       buf = descriptor.m_partial_buffer->getBuffer();
+               }
+               else {
+                       buf = descriptor.m_buffer;
+               }
+
+               // Check and abort if the machine is swapping a lot
+               if (draw.getTimerTime() > 1000) {
+                       infostream << "ClientMap::renderMapShadows(): Rendering "
+                                       "took >1s, returning." << std::endl;
+                       break;
+               }
 
-                       drawcall_count += list.bufs.size();
+               if (!descriptor.m_reuse_material) {
+                       // override some material properties
+                       video::SMaterial local_material = buf->getMaterial();
+                       local_material.MaterialType = material.MaterialType;
+                       local_material.BackfaceCulling = material.BackfaceCulling;
+                       local_material.FrontfaceCulling = material.FrontfaceCulling;
+                       local_material.BlendOperation = material.BlendOperation;
+                       local_material.Lighting = false;
+                       driver->setMaterial(local_material);
+                       ++material_swaps;
                }
+
+               v3f block_wpos = intToFloat(descriptor.m_pos * MAP_BLOCKSIZE, BS);
+               m.setTranslation(block_wpos - offset);
+
+               driver->setTransform(video::ETS_WORLD, m);
+               driver->drawMeshBuffer(buf);
+               vertex_count += buf->getIndexCount();
        }
 
-       // restore the driver material state 
+       // restore the driver material state
        video::SMaterial clean;
        clean.BlendOperation = video::EBO_ADD;
        driver->setMaterial(clean); // reset material to defaults
        driver->draw3DLine(v3f(), v3f(), video::SColor(0));
-       
+
        g_profiler->avg(prefix + "draw meshes [ms]", draw.stop(true));
        g_profiler->avg(prefix + "vertices drawn [#]", vertex_count);
        g_profiler->avg(prefix + "drawcalls [#]", drawcall_count);
+       g_profiler->avg(prefix + "material swaps [#]", material_swaps);
 }
 
 /*
        Custom update draw list for the pov of shadow light.
 */
-void ClientMap::updateDrawListShadow(const v3f &shadow_light_pos, const v3f &shadow_light_dir, float shadow_range)
+void ClientMap::updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length)
 {
        ScopeProfiler sp(g_profiler, "CM::updateDrawListShadow()", SPT_AVG);
 
-       const v3f camera_position = shadow_light_pos;
-       const v3f camera_direction = shadow_light_dir;
-       // I "fake" fov just to avoid creating a new function to handle orthographic
-       // projection.
-       const f32 camera_fov = m_camera_fov * 1.9f;
-
-       v3s16 cam_pos_nodes = floatToInt(camera_position, BS);
+       v3s16 cam_pos_nodes = floatToInt(shadow_light_pos, BS);
        v3s16 p_blocks_min;
        v3s16 p_blocks_max;
-       getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max, shadow_range);
+       getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max, radius + length);
 
        std::vector<v2s16> blocks_in_range;
 
@@ -774,15 +879,6 @@ void ClientMap::updateDrawListShadow(const v3f &shadow_light_pos, const v3f &sha
        }
        m_drawlist_shadow.clear();
 
-       // We need to append the blocks from the camera POV because sometimes
-       // they are not inside the light frustum and it creates glitches.
-       // FIXME: This could be removed if we figure out why they are missing
-       // from the light frustum.
-       for (auto &i : m_drawlist) {
-               i.second->refGrab();
-               m_drawlist_shadow[i.first] = i.second;
-       }
-
        // Number of blocks currently loaded by the client
        u32 blocks_loaded = 0;
        // Number of blocks with mesh in rendering range
@@ -808,23 +904,13 @@ void ClientMap::updateDrawListShadow(const v3f &shadow_light_pos, const v3f &sha
                                continue;
                        }
 
-                       float range = shadow_range;
-
-                       float d = 0.0;
-                       if (!isBlockInSight(block->getPos(), camera_position,
-                                           camera_direction, camera_fov, range, &d))
+                       v3f block_pos = intToFloat(block->getPos() * MAP_BLOCKSIZE, BS);
+                       v3f projection = shadow_light_pos + shadow_light_dir * shadow_light_dir.dotProduct(block_pos - shadow_light_pos);
+                       if (projection.getDistanceFrom(block_pos) > radius)
                                continue;
 
                        blocks_in_range_with_mesh++;
 
-                       /*
-                               Occlusion culling
-                       */
-                       if (isBlockOccluded(block, cam_pos_nodes)) {
-                               blocks_occlusion_culled++;
-                               continue;
-                       }
-
                        // This block is in range. Reset usage timer.
                        block->resetUsageTimer();
 
@@ -841,3 +927,40 @@ void ClientMap::updateDrawListShadow(const v3f &shadow_light_pos, const v3f &sha
        g_profiler->avg("SHADOW MapBlocks drawn [#]", m_drawlist_shadow.size());
        g_profiler->avg("SHADOW MapBlocks loaded [#]", blocks_loaded);
 }
+
+void ClientMap::updateTransparentMeshBuffers()
+{
+       ScopeProfiler sp(g_profiler, "CM::updateTransparentMeshBuffers", SPT_AVG);
+       u32 sorted_blocks = 0;
+       u32 unsorted_blocks = 0;
+       f32 sorting_distance_sq = pow(m_cache_transparency_sorting_distance * BS, 2.0f);
+
+
+       // Update the order of transparent mesh buffers in each mesh
+       for (auto it = m_drawlist.begin(); it != m_drawlist.end(); it++) {
+               MapBlock* block = it->second;
+               if (!block->mesh)
+                       continue;
+               
+               if (m_needs_update_transparent_meshes || 
+                               block->mesh->getTransparentBuffers().size() == 0) {
+
+                       v3s16 block_pos = block->getPos();
+                       v3f block_pos_f = intToFloat(block_pos * MAP_BLOCKSIZE + MAP_BLOCKSIZE / 2, BS);
+                       f32 distance = m_camera_position.getDistanceFromSQ(block_pos_f);
+                       if (distance <= sorting_distance_sq) {
+                               block->mesh->updateTransparentBuffers(m_camera_position, block_pos);
+                               ++sorted_blocks;
+                       }
+                       else {
+                               block->mesh->consolidateTransparentBuffers();
+                               ++unsorted_blocks;
+                       }
+               }
+       }
+
+       g_profiler->avg("CM::Transparent Buffers - Sorted", sorted_blocks);
+       g_profiler->avg("CM::Transparent Buffers - Unsorted", unsorted_blocks);
+       m_needs_update_transparent_meshes = false;
+}
+
index 97ce8d355f2d2a3fd3965476d59075ce3d887d7c..6d57f1911571c1471db23e775ce641df4357e83c 100644 (file)
@@ -56,6 +56,7 @@ struct MeshBufListList
 
 class Client;
 class ITextureSource;
+class PartialMeshBuffer;
 
 /*
        ClientMap
@@ -75,45 +76,37 @@ class ClientMap : public Map, public scene::ISceneNode
 
        virtual ~ClientMap() = default;
 
-       s32 mapType() const
+       bool maySaveBlocks() override
        {
-               return MAPTYPE_CLIENT;
+               return false;
        }
 
-       void drop()
+       void drop() override
        {
-               ISceneNode::drop();
+               ISceneNode::drop(); // calls destructor
        }
 
-       void updateCamera(const v3f &pos, const v3f &dir, f32 fov, const v3s16 &offset)
-       {
-               m_camera_position = pos;
-               m_camera_direction = dir;
-               m_camera_fov = fov;
-               m_camera_offset = offset;
-       }
+       void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset);
 
        /*
                Forcefully get a sector from somewhere
        */
-       MapSector * emergeSector(v2s16 p);
-
-       //void deSerializeSector(v2s16 p2d, std::istream &is);
+       MapSector * emergeSector(v2s16 p) override;
 
        /*
                ISceneNode methods
        */
 
-       virtual void OnRegisterSceneNode();
+       virtual void OnRegisterSceneNode() override;
 
-       virtual void render()
+       virtual void render() override
        {
                video::IVideoDriver* driver = SceneManager->getVideoDriver();
                driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
                renderMap(driver, SceneManager->getSceneNodeRenderPass());
        }
 
-       virtual const aabb3f &getBoundingBox() const
+       virtual const aabb3f &getBoundingBox() const override
        {
                return m_box;
        }
@@ -121,7 +114,9 @@ class ClientMap : public Map, public scene::ISceneNode
        void getBlocksInViewRange(v3s16 cam_pos_nodes,
                v3s16 *p_blocks_min, v3s16 *p_blocks_max, float range=-1.0f);
        void updateDrawList();
-       void updateDrawListShadow(const v3f &shadow_light_pos, const v3f &shadow_light_dir, float shadow_range);
+       void updateDrawListShadow(v3f shadow_light_pos, v3f shadow_light_dir, float radius, float length);
+       // Returns true if draw list needs updating before drawing the next frame.
+       bool needsUpdateDrawList() { return m_needs_update_drawlist; }
        void renderMap(video::IVideoDriver* driver, s32 pass);
 
        void renderMapShadows(video::IVideoDriver *driver,
@@ -133,13 +128,54 @@ class ClientMap : public Map, public scene::ISceneNode
        void renderPostFx(CameraMode cam_mode);
 
        // For debug printing
-       virtual void PrintInfo(std::ostream &out);
+       void PrintInfo(std::ostream &out) override;
 
        const MapDrawControl & getControl() const { return m_control; }
        f32 getWantedRange() const { return m_control.wanted_range; }
        f32 getCameraFov() const { return m_camera_fov; }
 
 private:
+
+       // update the vertex order in transparent mesh buffers
+       void updateTransparentMeshBuffers();
+
+       // Orders blocks by distance to the camera
+       class MapBlockComparer
+       {
+       public:
+               MapBlockComparer(const v3s16 &camera_block) : m_camera_block(camera_block) {}
+
+               bool operator() (const v3s16 &left, const v3s16 &right) const
+               {
+                       auto distance_left = left.getDistanceFromSQ(m_camera_block);
+                       auto distance_right = right.getDistanceFromSQ(m_camera_block);
+                       return distance_left > distance_right || (distance_left == distance_right && left > right);
+               }
+
+       private:
+               v3s16 m_camera_block;
+       };
+
+
+       // reference to a mesh buffer used when rendering the map.
+       struct DrawDescriptor {
+               v3s16 m_pos;
+               union {
+                       scene::IMeshBuffer *m_buffer;
+                       const PartialMeshBuffer *m_partial_buffer;
+               };
+               bool m_reuse_material:1;
+               bool m_use_partial_buffer:1;
+
+               DrawDescriptor(v3s16 pos, scene::IMeshBuffer *buffer, bool reuse_material) :
+                       m_pos(pos), m_buffer(buffer), m_reuse_material(reuse_material), m_use_partial_buffer(false)
+               {}
+
+               DrawDescriptor(v3s16 pos, const PartialMeshBuffer *buffer) :
+                       m_pos(pos), m_partial_buffer(buffer), m_reuse_material(false), m_use_partial_buffer(true)
+               {}
+       };
+
        Client *m_client;
        RenderingEngine *m_rendering_engine;
 
@@ -152,9 +188,11 @@ class ClientMap : public Map, public scene::ISceneNode
        v3f m_camera_direction = v3f(0,0,1);
        f32 m_camera_fov = M_PI;
        v3s16 m_camera_offset;
+       bool m_needs_update_transparent_meshes = true;
 
-       std::map<v3s16, MapBlock*> m_drawlist;
+       std::map<v3s16, MapBlock*, MapBlockComparer> m_drawlist;
        std::map<v3s16, MapBlock*> m_drawlist_shadow;
+       bool m_needs_update_drawlist;
 
        std::set<v2s16> m_last_drawn_sectors;
 
@@ -162,4 +200,5 @@ class ClientMap : public Map, public scene::ISceneNode
        bool m_cache_bilinear_filter;
        bool m_cache_anistropic_filter;
        bool m_added_to_shadow_renderer{false};
+       u16 m_cache_transparency_sorting_distance;
 };
index aa7b0f3985cd9d688bc5e2274a13e7b04c0888f5..c297d737fc88da0ac058a8e50028be3311748ee2 100644 (file)
@@ -174,12 +174,12 @@ class ClientMediaDownloader : public IClientMediaDownloader
        s32 m_uncached_received_count = 0;
 
        // Status of remote transfers
-       unsigned long m_httpfetch_caller;
-       unsigned long m_httpfetch_next_id = 0;
+       u64 m_httpfetch_caller;
+       u64 m_httpfetch_next_id = 0;
        s32 m_httpfetch_active = 0;
        s32 m_httpfetch_active_limit = 0;
        s32 m_outstanding_hash_sets = 0;
-       std::unordered_map<unsigned long, std::string> m_remote_file_transfers;
+       std::unordered_map<u64, std::string> m_remote_file_transfers;
 
        // All files up to this name have either been received from a
        // remote server or failed on all remote servers, so those files
index c009a05b76b76601666a7ae4524e06fcac4a3984..6db88d93c5b7f5ce93e441243b18b35567450c98 100644 (file)
@@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes_extrabloated.h"
 #include <iostream>
 #include "constants.h"
-#include "cloudparams.h"
+#include "skyparams.h"
 
 // Menu clouds
 class Clouds;
index 5d8a597a2c41618c4a8743edd58b5a444fc2e075..ec1fd1c2affadd2c718ab8207a1728d9b3889bd4 100644 (file)
@@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client/sound.h"
 #include "client/tile.h"
 #include "util/basic_macros.h"
-#include "util/numeric.h" // For IntervalLimiter & setPitchYawRoll
+#include "util/numeric.h"
 #include "util/serialize.h"
 #include "camera.h" // CameraModes
 #include "collision.h"
@@ -172,6 +172,20 @@ static void updatePositionRecursive(scene::ISceneNode *node)
        node->updateAbsolutePosition();
 }
 
+static bool logOnce(const std::ostringstream &from, std::ostream &log_to)
+{
+       thread_local std::vector<u64> logged;
+
+       std::string message = from.str();
+       u64 hash = murmur_hash_64_ua(message.data(), message.length(), 0xBADBABE);
+
+       if (std::find(logged.begin(), logged.end(), hash) != logged.end())
+               return false;
+       logged.push_back(hash);
+       log_to << message << std::endl;
+       return true;
+}
+
 /*
        TestCAO
 */
@@ -422,7 +436,7 @@ const v3f GenericCAO::getPosition() const
        return m_position;
 }
 
-const bool GenericCAO::isImmortal()
+bool GenericCAO::isImmortal() const
 {
        return itemgroup_get(getGroups(), "immortal");
 }
@@ -651,7 +665,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
                                m_matrixnode, v2f(1, 1), v3f(0,0,0), -1);
                m_spritenode->grab();
                m_spritenode->setMaterialTexture(0,
-                               tsrc->getTextureForMesh("unknown_node.png"));
+                               tsrc->getTextureForMesh("no_texture.png"));
 
                setSceneNodeMaterial(m_spritenode);
 
@@ -735,9 +749,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
                m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
                m_meshnode->grab();
                mesh->drop();
-               // Set it to use the materials of the meshbuffers directly.
-               // This is needed for changing the texture in the future
-               m_meshnode->setReadOnlyMaterials(true);
        } else if (m_prop.visual == "cube") {
                grabMatrixNode();
                scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
@@ -754,10 +765,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
                grabMatrixNode();
                scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true);
                if (mesh) {
-                       m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode);
-                       m_animated_meshnode->grab();
-                       mesh->drop(); // The scene node took hold of it
-
                        if (!checkMeshNormals(mesh)) {
                                infostream << "GenericCAO: recalculating normals for mesh "
                                        << m_prop.mesh << std::endl;
@@ -765,6 +772,9 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
                                                recalculateNormals(mesh, true, false);
                        }
 
+                       m_animated_meshnode = m_smgr->addAnimatedMeshSceneNode(mesh, m_matrixnode);
+                       m_animated_meshnode->grab();
+                       mesh->drop(); // The scene node took hold of it
                        m_animated_meshnode->animateJoints(); // Needed for some animations
                        m_animated_meshnode->setScale(m_prop.visual_size);
 
@@ -827,12 +837,33 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
        setNodeLight(m_last_light);
        updateMeshCulling();
 
+       if (m_animated_meshnode) {
+               u32 mat_count = m_animated_meshnode->getMaterialCount();
+               if (mat_count == 0 || m_prop.textures.empty()) {
+                       // nothing
+               } else if (mat_count > m_prop.textures.size()) {
+                       std::ostringstream oss;
+                       oss << "GenericCAO::addToScene(): Model "
+                               << m_prop.mesh << " loaded with " << mat_count
+                               << " mesh buffers but only " << m_prop.textures.size()
+                               << " texture(s) specifed, this is deprecated.";
+                       logOnce(oss, warningstream);
+
+                       video::ITexture *last = m_animated_meshnode->getMaterial(0).TextureLayer[0].Texture;
+                       for (u32 i = 1; i < mat_count; i++) {
+                               auto &layer = m_animated_meshnode->getMaterial(i).TextureLayer[0];
+                               if (!layer.Texture)
+                                       layer.Texture = last;
+                               last = layer.Texture;
+                       }
+               }
+       }
+
        if (m_client->modsLoaded() && m_client->getScript()->on_object_add(m_id)) {
                removeFromScene(false);
                return;
        }
 
-
        if (m_client->modsLoaded())
                m_client->getScript()->on_object_properties_change(m_id);
 }
@@ -842,7 +873,8 @@ void GenericCAO::updateLight(u32 day_night_ratio)
        if (m_glow < 0)
                return;
 
-       u8 light_at_pos = 0;
+       u16 light_at_pos = 0;
+       u8 light_at_pos_intensity = 0;
        bool pos_ok = false;
 
        v3s16 pos[3];
@@ -851,30 +883,36 @@ void GenericCAO::updateLight(u32 day_night_ratio)
                bool this_ok;
                MapNode n = m_env->getMap().getNode(pos[i], &this_ok);
                if (this_ok) {
-                       u8 this_light = n.getLightBlend(day_night_ratio, m_client->ndef());
-                       light_at_pos = MYMAX(light_at_pos, this_light);
+                       u16 this_light = getInteriorLight(n, 0, m_client->ndef());
+                       u8 this_light_intensity = MYMAX(this_light & 0xFF, (this_light >> 8) && 0xFF);
+                       if (this_light_intensity > light_at_pos_intensity) {
+                               light_at_pos = this_light;
+                               light_at_pos_intensity = this_light_intensity;
+                       }
                        pos_ok = true;
                }
        }
        if (!pos_ok)
-               light_at_pos = blend_light(day_night_ratio, LIGHT_SUN, 0);
+               light_at_pos = LIGHT_SUN;
+
+       video::SColor light = encode_light(light_at_pos, m_glow);
+       if (!m_enable_shaders)
+               final_color_blend(&light, light_at_pos, day_night_ratio);
 
-       u8 light = decode_light(light_at_pos + m_glow);
        if (g_settings->getBool("fullbright"))
-               light = 255;
+               light = video::SColor(0xFFFFFFFF);
+
        if (light != m_last_light) {
                m_last_light = light;
                setNodeLight(light);
        }
 }
 
-void GenericCAO::setNodeLight(u8 light)
+void GenericCAO::setNodeLight(const video::SColor &light_color)
 {
-       video::SColor color(255, light, light, light);
-
        if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
                if (m_wield_meshnode)
-                       m_wield_meshnode->setNodeLightColor(color);
+                       m_wield_meshnode->setNodeLightColor(light_color);
                return;
        }
 
@@ -886,7 +924,7 @@ void GenericCAO::setNodeLight(u8 light)
                        scene::IMesh *mesh = m_meshnode->getMesh();
                        for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
                                scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
-                               buf->getMaterial().EmissiveColor = color;
+                               buf->getMaterial().EmissiveColor = light_color;
                        }
                } else {
                        scene::ISceneNode *node = getSceneNode();
@@ -895,16 +933,16 @@ void GenericCAO::setNodeLight(u8 light)
 
                        for (u32 i = 0; i < node->getMaterialCount(); ++i) {
                                video::SMaterial &material = node->getMaterial(i);
-                               material.EmissiveColor = color;
+                               material.EmissiveColor = light_color;
                        }
                }
        } else {
                if (m_meshnode) {
-                       setMeshColor(m_meshnode->getMesh(), color);
+                       setMeshColor(m_meshnode->getMesh(), light_color);
                } else if (m_animated_meshnode) {
-                       setAnimatedMeshColor(m_animated_meshnode, color);
+                       setAnimatedMeshColor(m_animated_meshnode, light_color);
                } else if (m_spritenode) {
-                       m_spritenode->setColor(color);
+                       m_spritenode->setColor(light_color);
                }
        }
 }
@@ -1014,12 +1052,14 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                        m_velocity = v3f(0,0,0);
                        m_acceleration = v3f(0,0,0);
                        const PlayerControl &controls = player->getPlayerControl();
+                       f32 new_speed = player->local_animation_speed;
 
                        bool walking = false;
-                       if (controls.movement_speed > 0.001f && ! g_settings->getBool("freecam"))
+                       if (controls.movement_speed > 0.001f && ! g_settings->getBool("freecam")) {
+                               new_speed *= controls.movement_speed;
                                walking = true;
+                       }
 
-                       f32 new_speed = player->local_animation_speed;
                        v2s32 new_anim = v2s32(0,0);
                        bool allow_update = false;
 
@@ -1034,7 +1074,6 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
                        // slowdown speed if sneaking
                        if (controls.sneak && walking && ! g_settings->getBool("no_slow"))
                                new_speed /= 2;
-                       new_speed *= controls.movement_speed;
 
                        if (walking && (controls.dig || controls.place)) {
                                new_anim = player->local_animations[3];
@@ -1304,9 +1343,15 @@ void GenericCAO::updateTextures(std::string mod)
        m_current_texture_modifier = mod;
        m_glow = m_prop.glow;
 
+       video::ITexture *shadow_texture = nullptr;
+       if (auto shadow = RenderingEngine::get_shadow_renderer())
+               shadow_texture = shadow->get_texture();
+
+       const u32 TEXTURE_LAYER_SHADOW = 3;
+
        if (m_spritenode) {
                if (m_prop.visual == "sprite") {
-                       std::string texturestring = "unknown_node.png";
+                       std::string texturestring = "no_texture.png";
                        if (!m_prop.textures.empty())
                                texturestring = m_prop.textures[0];
                        texturestring += mod;
@@ -1314,6 +1359,7 @@ void GenericCAO::updateTextures(std::string mod)
                        m_spritenode->getMaterial(0).MaterialTypeParam = 0.5f;
                        m_spritenode->setMaterialTexture(0,
                                        tsrc->getTextureForMesh(texturestring));
+                       m_spritenode->setMaterialTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                        // This allows setting per-material colors. However, until a real lighting
                        // system is added, the code below will have no effect. Once MineTest
@@ -1349,6 +1395,7 @@ void GenericCAO::updateTextures(std::string mod)
                                material.MaterialType = m_material_type;
                                material.MaterialTypeParam = 0.5f;
                                material.TextureLayer[0].Texture = texture;
+                               material.TextureLayer[TEXTURE_LAYER_SHADOW].Texture = shadow_texture;
                                material.setFlag(video::EMF_LIGHTING, true);
                                material.setFlag(video::EMF_BILINEAR_FILTER, false);
                                material.setFlag(video::EMF_BACK_FACE_CULLING, m_prop.backface_culling);
@@ -1385,7 +1432,7 @@ void GenericCAO::updateTextures(std::string mod)
                {
                        for (u32 i = 0; i < 6; ++i)
                        {
-                               std::string texturestring = "unknown_node.png";
+                               std::string texturestring = "no_texture.png";
                                if(m_prop.textures.size() > i)
                                        texturestring = m_prop.textures[i];
                                texturestring += mod;
@@ -1399,6 +1446,7 @@ void GenericCAO::updateTextures(std::string mod)
                                material.setFlag(video::EMF_BILINEAR_FILTER, false);
                                material.setTexture(0,
                                                tsrc->getTextureForMesh(texturestring));
+                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
                                material.getTextureMatrix(0).makeIdentity();
 
                                // This allows setting per-material colors. However, until a real lighting
@@ -1418,54 +1466,56 @@ void GenericCAO::updateTextures(std::string mod)
                } else if (m_prop.visual == "upright_sprite") {
                        scene::IMesh *mesh = m_meshnode->getMesh();
                        {
-                               std::string tname = "unknown_object.png";
+                               std::string tname = "no_texture.png";
                                if (!m_prop.textures.empty())
                                        tname = m_prop.textures[0];
                                tname += mod;
-                               scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
-                               buf->getMaterial().setTexture(0,
+                               auto& material = m_meshnode->getMaterial(0);
+                               material.setTexture(0,
                                                tsrc->getTextureForMesh(tname));
+                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                                // This allows setting per-material colors. However, until a real lighting
                                // system is added, the code below will have no effect. Once MineTest
                                // has directional lighting, it should work automatically.
                                if(!m_prop.colors.empty()) {
-                                       buf->getMaterial().AmbientColor = m_prop.colors[0];
-                                       buf->getMaterial().DiffuseColor = m_prop.colors[0];
-                                       buf->getMaterial().SpecularColor = m_prop.colors[0];
+                                       material.AmbientColor = m_prop.colors[0];
+                                       material.DiffuseColor = m_prop.colors[0];
+                                       material.SpecularColor = m_prop.colors[0];
                                }
 
-                               buf->getMaterial().setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
+                               material.setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
+                               material.setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
+                               material.setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
                        }
                        {
-                               std::string tname = "unknown_object.png";
+                               std::string tname = "no_texture.png";
                                if (m_prop.textures.size() >= 2)
                                        tname = m_prop.textures[1];
                                else if (!m_prop.textures.empty())
                                        tname = m_prop.textures[0];
                                tname += mod;
-                               scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
-                               buf->getMaterial().setTexture(0,
+                               auto& material = m_meshnode->getMaterial(1);
+                               material.setTexture(0,
                                                tsrc->getTextureForMesh(tname));
+                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                                // This allows setting per-material colors. However, until a real lighting
                                // system is added, the code below will have no effect. Once MineTest
                                // has directional lighting, it should work automatically.
                                if (m_prop.colors.size() >= 2) {
-                                       buf->getMaterial().AmbientColor = m_prop.colors[1];
-                                       buf->getMaterial().DiffuseColor = m_prop.colors[1];
-                                       buf->getMaterial().SpecularColor = m_prop.colors[1];
+                                       material.AmbientColor = m_prop.colors[1];
+                                       material.DiffuseColor = m_prop.colors[1];
+                                       material.SpecularColor = m_prop.colors[1];
                                } else if (!m_prop.colors.empty()) {
-                                       buf->getMaterial().AmbientColor = m_prop.colors[0];
-                                       buf->getMaterial().DiffuseColor = m_prop.colors[0];
-                                       buf->getMaterial().SpecularColor = m_prop.colors[0];
+                                       material.AmbientColor = m_prop.colors[0];
+                                       material.DiffuseColor = m_prop.colors[0];
+                                       material.SpecularColor = m_prop.colors[0];
                                }
 
-                               buf->getMaterial().setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
+                               material.setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
+                               material.setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
+                               material.setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
                        }
                        // Set mesh color (only if lighting is disabled)
                        if (!m_prop.colors.empty() && m_glow < 0)
@@ -1811,6 +1861,7 @@ void GenericCAO::processMessage(const std::string &data)
                        {
                                        updateAnimation();
                        }
+                       // FIXME: ^ This code is trash. It's also broken.
                }
        } else if (cmd == AO_CMD_SET_ANIMATION_SPEED) {
                m_animation_speed = readF32(is);
@@ -1855,6 +1906,8 @@ void GenericCAO::processMessage(const std::string &data)
                                m_reset_textures_timer = 0.05;
                                if(damage >= 2)
                                        m_reset_textures_timer += 0.05 * damage;
+                               // Cap damage overlay to 1 second
+                               m_reset_textures_timer = std::min(m_reset_textures_timer, 1.0f);
                                updateTextures(m_current_texture_modifier + m_prop.damage_texture_modifier);
                        }
                }
@@ -1905,7 +1958,8 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem,
                        m_armor_groups,
                        toolcap,
                        punchitem,
-                       time_from_last_punch);
+                       time_from_last_punch,
+                       punchitem->wear);
 
        if(result.did_punch && result.damage != 0)
        {
@@ -1925,6 +1979,8 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem,
                        m_reset_textures_timer = 0.05;
                        if (result.damage >= 2)
                                m_reset_textures_timer += 0.05 * result.damage;
+                       // Cap damage overlay to 1 second
+                       m_reset_textures_timer = std::min(m_reset_textures_timer, 1.0f);
                        updateTextures(m_current_texture_modifier + m_prop.damage_texture_modifier);
                }
        }
@@ -1953,20 +2009,17 @@ void GenericCAO::updateMeshCulling()
 
        const bool hidden = m_client->getCamera()->getCameraMode() == CAMERA_MODE_FIRST && ! g_settings->getBool("freecam");
 
-       if (m_meshnode && m_prop.visual == "upright_sprite") {
-               u32 buffers = m_meshnode->getMesh()->getMeshBufferCount();
-               for (u32 i = 0; i < buffers; i++) {
-                       video::SMaterial &mat = m_meshnode->getMesh()->getMeshBuffer(i)->getMaterial();
-                       // upright sprite has no backface culling
-                       mat.setFlag(video::EMF_FRONT_FACE_CULLING, hidden);
-               }
-               return;
-       }
-
        scene::ISceneNode *node = getSceneNode();
+
        if (!node)
                return;
 
+       if (m_prop.visual == "upright_sprite") {
+               // upright sprite has no backface culling
+               node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, hidden);
+               return;
+       }
+
        if (hidden) {
                // Hide the mesh by culling both front and
                // back faces. Serious hackyness but it works for our
index 7e9bb6671e1262254724db27a53fbceb389d2f27..8e5d04bfac2e572857ee0710e0d08a9d43aef44b 100644 (file)
@@ -125,7 +125,7 @@ class GenericCAO : public ClientActiveObject
        std::string m_current_texture_modifier = "";
        bool m_visuals_expired = false;
        float m_step_distance_counter = 0.0f;
-       u8 m_last_light = 255;
+       video::SColor m_last_light = video::SColor(0xFFFFFFFF);
        bool m_is_visible = false;
        s8 m_glow = 0;
        // Material
@@ -182,12 +182,12 @@ class GenericCAO : public ClientActiveObject
                return m_velocity;
        }
 
-       inline const u16 getHp() const
+       inline u16 getHp() const
        {
                return m_hp;
        }
 
-       const bool isImmortal();
+       bool isImmortal() const;
 
        inline const ObjectProperties &getProperties() const { return m_prop; }
 
@@ -271,7 +271,7 @@ class GenericCAO : public ClientActiveObject
 
        void updateLight(u32 day_night_ratio);
 
-       void setNodeLight(u8 light);
+       void setNodeLight(const video::SColor &light);
 
        /* Get light position(s).
         * returns number of positions written into pos[], which must have space
index bb2d6398f1015c855a19d07dc3f495fbcaeaafa2..8675275aa4a298e15c5b2554adb959ac838ce2a6 100644 (file)
@@ -150,8 +150,10 @@ void MapblockMeshGenerator::drawQuad(v3f *coords, const v3s16 &normal,
 //              should be (2+2)*6=24 values in the list. The order of
 //              the faces in the list is up-down-right-left-back-front
 //              (compatible with ContentFeatures).
+//  mask      - a bit mask that suppresses drawing of tiles.
+//              tile i will not be drawn if mask & (1 << i) is 1
 void MapblockMeshGenerator::drawCuboid(const aabb3f &box,
-       TileSpec *tiles, int tilecount, const LightInfo *lights, const f32 *txc)
+       TileSpec *tiles, int tilecount, const LightInfo *lights, const f32 *txc, u8 mask)
 {
        assert(tilecount >= 1 && tilecount <= 6); // pre-condition
 
@@ -274,6 +276,8 @@ void MapblockMeshGenerator::drawCuboid(const aabb3f &box,
 
        // Add to mesh collector
        for (int k = 0; k < 6; ++k) {
+               if (mask & (1 << k))
+                       continue;
                int tileindex = MYMIN(k, tilecount - 1);
                collector->append(tiles[tileindex], vertices + 4 * k, 4, quad_indices, 6);
        }
@@ -363,7 +367,7 @@ void MapblockMeshGenerator::generateCuboidTextureCoords(const aabb3f &box, f32 *
 }
 
 void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc,
-       TileSpec *tiles, int tile_count)
+       TileSpec *tiles, int tile_count, u8 mask)
 {
        bool scale = std::fabs(f->visual_scale - 1.0f) > 1e-3f;
        f32 texture_coord_buf[24];
@@ -373,6 +377,10 @@ void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc,
        f32 dx2 = box.MaxEdge.X;
        f32 dy2 = box.MaxEdge.Y;
        f32 dz2 = box.MaxEdge.Z;
+
+       box.MinEdge += origin;
+       box.MaxEdge += origin;
+
        if (scale) {
                if (!txc) { // generate texture coords before scaling
                        generateCuboidTextureCoords(box, texture_coord_buf);
@@ -381,12 +389,11 @@ void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc,
                box.MinEdge *= f->visual_scale;
                box.MaxEdge *= f->visual_scale;
        }
-       box.MinEdge += origin;
-       box.MaxEdge += origin;
        if (!txc) {
                generateCuboidTextureCoords(box, texture_coord_buf);
                txc = texture_coord_buf;
        }
+
        if (!tiles) {
                tiles = &tile;
                tile_count = 1;
@@ -400,12 +407,49 @@ void MapblockMeshGenerator::drawAutoLightedCuboid(aabb3f box, const f32 *txc,
                        d.Z = (j & 1) ? dz2 : dz1;
                        lights[j] = blendLight(d);
                }
-               drawCuboid(box, tiles, tile_count, lights, txc);
+               drawCuboid(box, tiles, tile_count, lights, txc, mask);
        } else {
-               drawCuboid(box, tiles, tile_count, nullptr, txc);
+               drawCuboid(box, tiles, tile_count, nullptr, txc, mask);
        }
 }
 
+u8 MapblockMeshGenerator::getNodeBoxMask(aabb3f box, u8 solid_neighbors, u8 sametype_neighbors) const
+{
+       const f32 NODE_BOUNDARY = 0.5 * BS;
+
+       // For an oversized nodebox, return immediately
+       if (box.MaxEdge.X > NODE_BOUNDARY ||
+                       box.MinEdge.X < -NODE_BOUNDARY ||
+                       box.MaxEdge.Y >  NODE_BOUNDARY ||
+                       box.MinEdge.Y < -NODE_BOUNDARY ||
+                       box.MaxEdge.Z >  NODE_BOUNDARY ||
+                       box.MinEdge.Z < -NODE_BOUNDARY)
+               return 0;
+
+       // We can skip faces at node boundary if the matching neighbor is solid
+       u8 solid_mask =
+                       (box.MaxEdge.Y == NODE_BOUNDARY  ?  1 : 0) |
+                       (box.MinEdge.Y == -NODE_BOUNDARY ?  2 : 0) |
+                       (box.MaxEdge.X == NODE_BOUNDARY  ?  4 : 0) |
+                       (box.MinEdge.X == -NODE_BOUNDARY ?  8 : 0) |
+                       (box.MaxEdge.Z == NODE_BOUNDARY  ? 16 : 0) |
+                       (box.MinEdge.Z == -NODE_BOUNDARY ? 32 : 0);
+
+       u8 sametype_mask = 0;
+       if (f->alpha == AlphaMode::ALPHAMODE_OPAQUE) {
+               // In opaque nodeboxes, faces on opposite sides can cancel
+               // each other out if there is a matching neighbor of the same type
+               sametype_mask =
+                               ((solid_mask & 3) == 3 ? 3 : 0) |
+                               ((solid_mask & 12) == 12 ? 12 : 0) |
+                               ((solid_mask & 48) == 48 ? 48 : 0);
+       }
+
+       // Combine masks with actual neighbors to get the faces to be skipped
+       return (solid_mask & solid_neighbors) | (sametype_mask & sametype_neighbors);
+}
+
+
 void MapblockMeshGenerator::prepareLiquidNodeDrawing()
 {
        getSpecialTile(0, &tile_liquid_top);
@@ -1363,13 +1407,38 @@ void MapblockMeshGenerator::drawNodeboxNode()
                getTile(nodebox_tile_dirs[face], &tiles[face]);
        }
 
+       bool param2_is_rotation =
+                       f->param_type_2 == CPT2_COLORED_FACEDIR ||
+                       f->param_type_2 == CPT2_COLORED_WALLMOUNTED ||
+                       f->param_type_2 == CPT2_FACEDIR ||
+                       f->param_type_2 == CPT2_WALLMOUNTED;
+
+       bool param2_is_level =
+                       f->param_type_2 == CPT2_LEVELED;
+
        // locate possible neighboring nodes to connect to
        u8 neighbors_set = 0;
-       if (f->node_box.type == NODEBOX_CONNECTED) {
-               for (int dir = 0; dir != 6; dir++) {
-                       u8 flag = 1 << dir;
-                       v3s16 p2 = blockpos_nodes + p + nodebox_connection_dirs[dir];
-                       MapNode n2 = data->m_vmanip.getNodeNoEx(p2);
+       u8 solid_neighbors = 0;
+       u8 sametype_neighbors = 0;
+       for (int dir = 0; dir != 6; dir++) {
+               u8 flag = 1 << dir;
+               v3s16 p2 = blockpos_nodes + p + nodebox_tile_dirs[dir];
+               MapNode n2 = data->m_vmanip.getNodeNoEx(p2);
+
+               // mark neighbors that are the same node type
+               // and have the same rotation or higher level stored as param2
+               if (n2.param0 == n.param0 &&
+                               (!param2_is_rotation || n.param2 == n2.param2) &&
+                               (!param2_is_level || n.param2 <= n2.param2))
+                       sametype_neighbors |= flag;
+
+               // mark neighbors that are simple solid blocks
+               if (nodedef->get(n2).drawtype == NDT_NORMAL)
+                       solid_neighbors |= flag;
+
+               if (f->node_box.type == NODEBOX_CONNECTED) {
+                       p2 = blockpos_nodes + p + nodebox_connection_dirs[dir];
+                       n2 = data->m_vmanip.getNodeNoEx(p2);
                        if (nodedef->nodeboxConnects(n, n2, flag))
                                neighbors_set |= flag;
                }
@@ -1377,8 +1446,63 @@ void MapblockMeshGenerator::drawNodeboxNode()
 
        std::vector<aabb3f> boxes;
        n.getNodeBoxes(nodedef, &boxes, neighbors_set);
-       for (auto &box : boxes)
-               drawAutoLightedCuboid(box, nullptr, tiles, 6);
+
+       bool isTransparent = false;
+
+       for (const TileSpec &tile : tiles) {
+               if (tile.layers[0].isTransparent()) {
+                       isTransparent = true;
+                       break;
+               }
+       }
+
+       if (isTransparent) {
+               std::vector<float> sections;
+               // Preallocate 8 default splits + Min&Max for each nodebox
+               sections.reserve(8 + 2 * boxes.size());
+
+               for (int axis = 0; axis < 3; axis++) {
+                       // identify sections
+
+                       if (axis == 0) {
+                               // Default split at node bounds, up to 3 nodes in each direction
+                               for (float s = -3.5f * BS; s < 4.0f * BS; s += 1.0f * BS)
+                                       sections.push_back(s);
+                       }
+                       else {
+                               // Avoid readding the same 8 default splits for Y and Z
+                               sections.resize(8);
+                       }
+
+                       // Add edges of existing node boxes, rounded to 1E-3
+                       for (size_t i = 0; i < boxes.size(); i++) {
+                               sections.push_back(std::floor(boxes[i].MinEdge[axis] * 1E3) * 1E-3);
+                               sections.push_back(std::floor(boxes[i].MaxEdge[axis] * 1E3) * 1E-3);
+                       }
+
+                       // split the boxes at recorded sections
+                       // limit splits to avoid runaway crash if inner loop adds infinite splits
+                       // due to e.g. precision problems.
+                       // 100 is just an arbitrary, reasonably high number.
+                       for (size_t i = 0; i < boxes.size() && i < 100; i++) {
+                               aabb3f *box = &boxes[i];
+                               for (float section : sections) {
+                                       if (box->MinEdge[axis] < section && box->MaxEdge[axis] > section) {
+                                               aabb3f copy(*box);
+                                               copy.MinEdge[axis] = section;
+                                               box->MaxEdge[axis] = section;
+                                               boxes.push_back(copy);
+                                               box = &boxes[i]; // find new address of the box in case of reallocation
+                                       }
+                               }
+                       }
+               }
+       }
+
+       for (auto &box : boxes) {
+               u8 mask = getNodeBoxMask(box, solid_neighbors, sametype_neighbors);
+               drawAutoLightedCuboid(box, nullptr, tiles, 6, mask);
+       }
 }
 
 void MapblockMeshGenerator::drawMeshNode()
index 7344f05ee20cdcf7d307c38a74b9aa134bbd4cd5..b13748cbc03ac1d0565bd9a77a8d58345f191cae 100644 (file)
@@ -100,10 +100,11 @@ class MapblockMeshGenerator
 
 // cuboid drawing!
        void drawCuboid(const aabb3f &box, TileSpec *tiles, int tilecount,
-               const LightInfo *lights , const f32 *txc);
+               const LightInfo *lights , const f32 *txc, u8 mask = 0);
        void generateCuboidTextureCoords(aabb3f const &box, f32 *coords);
        void drawAutoLightedCuboid(aabb3f box, const f32 *txc = NULL,
-               TileSpec *tiles = NULL, int tile_count = 0);
+               TileSpec *tiles = NULL, int tile_count = 0, u8 mask = 0);
+       u8 getNodeBoxMask(aabb3f box, u8 solid_neighbors, u8 sametype_neighbors) const;
 
 // liquid-specific
        bool top_is_same_liquid;
index f64315db476a9f3355f17cc7ebd8a1ca9689b28e..ad8305b4583e9d7a39c1649f8103bec08b4bd4be 100644 (file)
@@ -24,10 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "porting.h"
 #include "filesys.h"
 #include "gettext.h"
-
-#if USE_FREETYPE
 #include "irrlicht_changes/CGUITTFont.h"
-#endif
 
 /** maximum size distance for getting a "similar" font size */
 #define MAX_FONT_SIZE_OFFSET 10
@@ -45,9 +42,8 @@ static void font_setting_changed(const std::string &name, void *userdata)
 FontEngine::FontEngine(gui::IGUIEnvironment* env) :
        m_env(env)
 {
-
        for (u32 &i : m_default_size) {
-               i = (FontMode) FONT_SIZE_UNSPECIFIED;
+               i = FONT_SIZE_UNSPECIFIED;
        }
 
        assert(g_settings != NULL); // pre-condition
@@ -56,23 +52,19 @@ FontEngine::FontEngine(gui::IGUIEnvironment* env) :
 
        readSettings();
 
-       if (m_currentMode != FM_Simple) {
-               g_settings->registerChangedCallback("font_size", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_bold", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_italic", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_path", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_path_bold", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_path_italic", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_path_bolditalic", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_shadow", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed, NULL);
-               g_settings->registerChangedCallback("fallback_font_path", font_setting_changed, NULL);
-       }
+       const char *settings[] = {
+               "font_size", "font_bold", "font_italic", "font_size_divisible_by",
+               "mono_font_size", "mono_font_size_divisible_by",
+               "font_shadow", "font_shadow_alpha",
+               "font_path", "font_path_bold", "font_path_italic", "font_path_bold_italic",
+               "mono_font_path", "mono_font_path_bold", "mono_font_path_italic",
+               "mono_font_path_bold_italic",
+               "fallback_font_path",
+               "screen_dpi", "gui_scaling",
+       };
 
-       g_settings->registerChangedCallback("mono_font_path", font_setting_changed, NULL);
-       g_settings->registerChangedCallback("mono_font_size", font_setting_changed, NULL);
-       g_settings->registerChangedCallback("screen_dpi", font_setting_changed, NULL);
-       g_settings->registerChangedCallback("gui_scaling", font_setting_changed, NULL);
+       for (auto name : settings)
+               g_settings->registerChangedCallback(name, font_setting_changed, NULL);
 }
 
 /******************************************************************************/
@@ -84,11 +76,13 @@ FontEngine::~FontEngine()
 /******************************************************************************/
 void FontEngine::cleanCache()
 {
+       RecursiveMutexAutoLock l(m_font_mutex);
+
        for (auto &font_cache_it : m_font_cache) {
 
                for (auto &font_it : font_cache_it) {
                        font_it.second->drop();
-                       font_it.second = NULL;
+                       font_it.second = nullptr;
                }
                font_cache_it.clear();
        }
@@ -104,16 +98,8 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
 {
        if (spec.mode == FM_Unspecified) {
                spec.mode = m_currentMode;
-       } else if (m_currentMode == FM_Simple) {
-               // Freetype disabled -> Force simple mode
-               spec.mode = (spec.mode == FM_Mono ||
-                               spec.mode == FM_SimpleMono) ?
-                               FM_SimpleMono : FM_Simple;
-               // Support for those could be added, but who cares?
-               spec.bold = false;
-               spec.italic = false;
        } else if (spec.mode == _FM_Fallback) {
-               // Fallback font doesn't support these either
+               // Fallback font doesn't support these
                spec.bold = false;
                spec.italic = false;
        }
@@ -122,17 +108,15 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
        if (spec.size == FONT_SIZE_UNSPECIFIED)
                spec.size = m_default_size[spec.mode];
 
+       RecursiveMutexAutoLock l(m_font_mutex);
+
        const auto &cache = m_font_cache[spec.getHash()];
        auto it = cache.find(spec.size);
        if (it != cache.end())
                return it->second;
 
        // Font does not yet exist
-       gui::IGUIFont *font = nullptr;
-       if (spec.mode == FM_Simple || spec.mode == FM_SimpleMono)
-               font = initSimpleFont(spec);
-       else
-               font = initFont(spec);
+       gui::IGUIFont *font = initFont(spec);
 
        if (!font && !may_fail) {
                errorstream << "Minetest cannot continue without a valid font. "
@@ -149,13 +133,7 @@ irr::gui::IGUIFont *FontEngine::getFont(FontSpec spec, bool may_fail)
 /******************************************************************************/
 unsigned int FontEngine::getTextHeight(const FontSpec &spec)
 {
-       irr::gui::IGUIFont *font = getFont(spec);
-
-       // use current skin font as fallback
-       if (font == NULL) {
-               font = m_env->getSkin()->getFont();
-       }
-       FATAL_ERROR_IF(font == NULL, "Could not get skin font");
+       gui::IGUIFont *font = getFont(spec);
 
        return font->getDimension(L"Some unimportant example String").Height;
 }
@@ -163,28 +141,15 @@ unsigned int FontEngine::getTextHeight(const FontSpec &spec)
 /******************************************************************************/
 unsigned int FontEngine::getTextWidth(const std::wstring &text, const FontSpec &spec)
 {
-       irr::gui::IGUIFont *font = getFont(spec);
-
-       // use current skin font as fallback
-       if (font == NULL) {
-               font = m_env->getSkin()->getFont();
-       }
-       FATAL_ERROR_IF(font == NULL, "Could not get font");
+       gui::IGUIFont *font = getFont(spec);
 
        return font->getDimension(text.c_str()).Width;
 }
 
-
 /** get line height for a specific font (including empty room between lines) */
 unsigned int FontEngine::getLineHeight(const FontSpec &spec)
 {
-       irr::gui::IGUIFont *font = getFont(spec);
-
-       // use current skin font as fallback
-       if (font == NULL) {
-               font = m_env->getSkin()->getFont();
-       }
-       FATAL_ERROR_IF(font == NULL, "Could not get font");
+       gui::IGUIFont *font = getFont(spec);
 
        return font->getDimension(L"Some unimportant example String").Height
                        + font->getKerningHeight();
@@ -198,13 +163,6 @@ unsigned int FontEngine::getDefaultFontSize()
 
 unsigned int FontEngine::getFontSize(FontMode mode)
 {
-       if (m_currentMode == FM_Simple) {
-               if (mode == FM_Mono || mode == FM_SimpleMono)
-                       return m_default_size[FM_SimpleMono];
-               else
-                       return m_default_size[FM_Simple];
-       }
-
        if (mode == FM_Unspecified)
                return m_default_size[FM_Standard];
 
@@ -214,20 +172,12 @@ unsigned int FontEngine::getFontSize(FontMode mode)
 /******************************************************************************/
 void FontEngine::readSettings()
 {
-       if (USE_FREETYPE && g_settings->getBool("freetype")) {
-               m_default_size[FM_Standard]  = g_settings->getU16("font_size");
-               m_default_size[_FM_Fallback] = g_settings->getU16("font_size");
-               m_default_size[FM_Mono]      = g_settings->getU16("mono_font_size");
-
-               m_default_bold = g_settings->getBool("font_bold");
-               m_default_italic = g_settings->getBool("font_italic");
+       m_default_size[FM_Standard]  = g_settings->getU16("font_size");
+       m_default_size[_FM_Fallback] = g_settings->getU16("font_size");
+       m_default_size[FM_Mono]      = g_settings->getU16("mono_font_size");
 
-       } else {
-               m_currentMode = FM_Simple;
-       }
-
-       m_default_size[FM_Simple]       = g_settings->getU16("font_size");
-       m_default_size[FM_SimpleMono]   = g_settings->getU16("mono_font_size");
+       m_default_bold = g_settings->getBool("font_bold");
+       m_default_italic = g_settings->getBool("font_italic");
 
        cleanCache();
        updateFontCache();
@@ -238,22 +188,9 @@ void FontEngine::readSettings()
 void FontEngine::updateSkin()
 {
        gui::IGUIFont *font = getFont();
+       assert(font);
 
-       if (font)
-               m_env->getSkin()->setFont(font);
-       else
-               errorstream << "FontEngine: Default font file: " <<
-                               "\n\t\"" << g_settings->get("font_path") << "\"" <<
-                               "\n\trequired for current screen configuration was not found" <<
-                               " or was invalid file format." <<
-                               "\n\tUsing irrlicht default font." << std::endl;
-
-       // If we did fail to create a font our own make irrlicht find a default one
-       font = m_env->getSkin()->getFont();
-       FATAL_ERROR_IF(font == NULL, "Could not create/get font");
-
-       u32 text_height = font->getDimension(L"Hello, world!").Height;
-       infostream << "FontEngine: measured text_height=" << text_height << std::endl;
+       m_env->getSkin()->setFont(font);
 }
 
 /******************************************************************************/
@@ -280,15 +217,18 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
        if (spec.italic)
                setting_suffix.append("_italic");
 
-       u32 size = std::floor(RenderingEngine::getDisplayDensity() *
-                       g_settings->getFloat("gui_scaling") * spec.size);
+       u32 size = std::max<u32>(spec.size * RenderingEngine::getDisplayDensity() *
+                       g_settings->getFloat("gui_scaling"), 1);
 
-       if (size == 0) {
-               errorstream << "FontEngine: attempt to use font size 0" << std::endl;
-               errorstream << "  display density: " << RenderingEngine::getDisplayDensity() << std::endl;
-               abort();
+       // Constrain the font size to a certain multiple, if necessary
+       u16 divisible_by = g_settings->getU16(setting_prefix + "font_size_divisible_by");
+       if (divisible_by > 1) {
+               size = std::max<u32>(
+                               std::round((double)size / divisible_by) * divisible_by, divisible_by);
        }
 
+       sanity_check(size != 0);
+
        u16 font_shadow       = 0;
        u16 font_shadow_alpha = 0;
        g_settings->getU16NoEx(setting_prefix + "font_shadow", font_shadow);
@@ -306,7 +246,6 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
                Settings::getLayer(SL_DEFAULTS)->get(path_setting)
        };
 
-#if USE_FREETYPE
        for (const std::string &font_path : fallback_settings) {
                gui::CGUITTFont *font = gui::CGUITTFont::createTTFont(m_env,
                                font_path.c_str(), size, true, true, font_shadow,
@@ -325,80 +264,5 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
                }
                return font;
        }
-#else
-       errorstream << "FontEngine: Tried to load TTF font but Minetest was"
-                       " compiled without Freetype." << std::endl;
-#endif
        return nullptr;
 }
-
-/** initialize a font without freetype */
-gui::IGUIFont *FontEngine::initSimpleFont(const FontSpec &spec)
-{
-       assert(spec.mode == FM_Simple || spec.mode == FM_SimpleMono);
-       assert(spec.size != FONT_SIZE_UNSPECIFIED);
-
-       const std::string &font_path = g_settings->get(
-                       (spec.mode == FM_SimpleMono) ? "mono_font_path" : "font_path");
-
-       size_t pos_dot = font_path.find_last_of('.');
-       std::string basename = font_path, ending;
-       if (pos_dot != std::string::npos)
-               ending = lowercase(font_path.substr(pos_dot));
-
-       if (ending == ".ttf") {
-               errorstream << "FontEngine: Found font \"" << font_path
-                               << "\" but freetype is not available." << std::endl;
-               return nullptr;
-       }
-
-       if (ending == ".xml" || ending == ".png")
-               basename = font_path.substr(0, pos_dot);
-
-       u32 size = std::floor(
-                       RenderingEngine::getDisplayDensity() *
-                       g_settings->getFloat("gui_scaling") *
-                       spec.size);
-
-       irr::gui::IGUIFont *font = nullptr;
-       std::string font_extensions[] = { ".png", ".xml" };
-
-       // Find nearest matching font scale
-       // Does a "zig-zag motion" (positibe/negative), from 0 to MAX_FONT_SIZE_OFFSET
-       for (s32 zoffset = 0; zoffset < MAX_FONT_SIZE_OFFSET * 2; zoffset++) {
-               std::stringstream path;
-
-               // LSB to sign
-               s32 sign = (zoffset & 1) ? -1 : 1;
-               s32 offset = zoffset >> 1;
-
-               for (const std::string &ext : font_extensions) {
-                       path.str(""); // Clear
-                       path << basename << "_" << (size + offset * sign) << ext;
-
-                       if (!fs::PathExists(path.str()))
-                               continue;
-
-                       font = m_env->getFont(path.str().c_str());
-
-                       if (font) {
-                               verbosestream << "FontEngine: found font: " << path.str() << std::endl;
-                               break;
-                       }
-               }
-
-               if (font)
-                       break;
-       }
-
-       // try name direct
-       if (font == NULL) {
-               if (fs::PathExists(font_path)) {
-                       font = m_env->getFont(font_path.c_str());
-                       if (font)
-                               verbosestream << "FontEngine: found font: " << font_path << std::endl;
-               }
-       }
-
-       return font;
-}
index 3d389ea48bfa32a1f51658fd2558aecc9f8cb92f..78608e517906c2f2471e68807af8608648def98d 100644 (file)
@@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #pragma once
 
 #include <map>
-#include <vector>
 #include "util/basic_macros.h"
 #include "irrlichttypes.h"
 #include <IGUIFont.h>
 #include <IGUISkin.h>
 #include <IGUIEnvironment.h>
 #include "settings.h"
+#include "threading/mutex_auto_lock.h"
 
 #define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF
 
@@ -34,8 +34,6 @@ enum FontMode : u8 {
        FM_Standard = 0,
        FM_Mono,
        _FM_Fallback, // do not use directly
-       FM_Simple,
-       FM_SimpleMono,
        FM_MaxMode,
        FM_Unspecified
 };
@@ -140,9 +138,6 @@ class FontEngine
        /** initialize a new TTF font */
        gui::IGUIFont *initFont(const FontSpec &spec);
 
-       /** initialize a font without freetype */
-       gui::IGUIFont *initSimpleFont(const FontSpec &spec);
-
        /** update current minetest skin with font changes */
        void updateSkin();
 
@@ -152,6 +147,9 @@ class FontEngine
        /** pointer to irrlicht gui environment */
        gui::IGUIEnvironment* m_env = nullptr;
 
+       /** mutex used to protect font init and cache */
+       std::recursive_mutex m_font_mutex;
+
        /** internal storage for caching fonts of different size */
        std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];
 
@@ -162,8 +160,8 @@ class FontEngine
        bool m_default_bold = false;
        bool m_default_italic = false;
 
-       /** current font engine mode */
-       FontMode m_currentMode = FM_Standard;
+       /** default font engine mode (fixed) */
+       static const FontMode m_currentMode = FM_Standard;
 
        DISABLE_CLASS_COPY(FontEngine);
 };
index d2a75104085d59555d1765dabecc77bca05be897..e439d0e32da366d7a056fa93b977c8fd34591a68 100644 (file)
@@ -122,7 +122,7 @@ Game::Game() :
 
        readSettings();
 
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        m_cache_hold_aux1 = false;      // This is initialised properly later
 #endif
 
@@ -243,19 +243,19 @@ bool Game::startup(bool *kill,
 void Game::run()
 {
        ProfilerGraph graph;
-       RunStats stats              = { 0 };
-       FpsControl draw_times       = { 0 };
+       RunStats stats = {};
+       FpsControl draw_times;
        f32 dtime; // in seconds
 
        /* Clear the profiler */
        Profiler::GraphValues dummyvalues;
        g_profiler->graphGet(dummyvalues);
 
-       draw_times.last_time = m_rendering_engine->get_timer_time();
+       draw_times.reset();
 
        set_light_table(g_settings->getFloat("display_gamma"));
 
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        m_cache_hold_aux1 = g_settings->getBool("fast_move")
                        && client->checkPrivilege("fast");
 #endif
@@ -283,7 +283,7 @@ void Game::run()
                // Calculate dtime =
                //    m_rendering_engine->run() from this iteration
                //  + Sleep time until the wanted FPS are reached
-               limitFps(&draw_times, &dtime);
+               draw_times.limit(device, &dtime);
 
                // Prepare render data for next iteration
 
@@ -313,10 +313,9 @@ void Game::run()
                step(&dtime);
                processClientEvents(&cam_view_target);
                updateDebugState();
-               updateCamera(draw_times.busy_time, dtime);
+               updateCamera(dtime);
                updateSound(dtime);
-               processPlayerInteraction(dtime, m_game_ui->m_flags.show_hud,
-                       m_game_ui->m_flags.show_basic_debug);
+               processPlayerInteraction(dtime, m_game_ui->m_flags.show_hud);
                updateFrame(&graph, &stats, dtime, cam_view);
                updateProfilerGraphs(&graph);
 
@@ -473,9 +472,8 @@ bool Game::createSingleplayerServer(const std::string &map_dir,
        }
 
        if (bind_addr.isIPv6() && !g_settings->getBool("enable_ipv6")) {
-               *error_message = "Unable to listen on " +
-                               bind_addr.serializeString() +
-                               " because IPv6 is disabled";
+               *error_message = fmtgettext("Unable to listen on %s because IPv6 is disabled",
+                       bind_addr.serializeString().c_str());
                errorstream << *error_message << std::endl;
                return false;
        }
@@ -508,7 +506,7 @@ bool Game::createClient(const GameStartData &start_data)
        if (!could_connect) {
                if (error_message->empty() && !connect_aborted) {
                        // Should not happen if error messages are set properly
-                       *error_message = "Connection failed for unknown reason";
+                       *error_message = gettext("Connection failed for unknown reason");
                        errorstream << *error_message << std::endl;
                }
                return false;
@@ -517,7 +515,7 @@ bool Game::createClient(const GameStartData &start_data)
        if (!getServerContent(&connect_aborted)) {
                if (error_message->empty() && !connect_aborted) {
                        // Should not happen if error messages are set properly
-                       *error_message = "Connection failed for unknown reason";
+                       *error_message = gettext("Connection failed for unknown reason");
                        errorstream << *error_message << std::endl;
                }
                return false;
@@ -533,8 +531,8 @@ bool Game::createClient(const GameStartData &start_data)
        /* Camera
         */
        camera = new Camera(*draw_control, client, m_rendering_engine);
-       if (!camera->successfullyCreated(*error_message))
-               return false;
+       if (client->modsLoaded())
+               client->getScript()->on_camera_ready(camera);
        client->setCamera(camera);
 
        /* Clouds
@@ -575,7 +573,7 @@ bool Game::createClient(const GameStartData &start_data)
                str += L" [";
                str += text;
                str += L"]";
-               delete text;
+               delete[] text;
        }
        str += L" [";
        str += L"Minetest Hackclient";
@@ -650,7 +648,6 @@ bool Game::connectToServer(const GameStartData &start_data,
                connect_address.Resolve(start_data.address.c_str());
 
                if (connect_address.isZero()) { // i.e. INADDR_ANY, IN6ADDR_ANY
-                       //connect_address.Resolve("localhost");
                        if (connect_address.isIPv6()) {
                                IPv6AddressBytes addr_bytes;
                                addr_bytes.bytes[15] = 1;
@@ -661,29 +658,35 @@ bool Game::connectToServer(const GameStartData &start_data,
                        local_server_mode = true;
                }
        } catch (ResolveError &e) {
-               *error_message = std::string("Couldn't resolve address: ") + e.what();
+               *error_message = fmtgettext("Couldn't resolve address: %s", e.what());
+
                errorstream << *error_message << std::endl;
                return false;
        }
 
        if (connect_address.isIPv6() && !g_settings->getBool("enable_ipv6")) {
-               *error_message = "Unable to connect to " +
-                               connect_address.serializeString() +
-                               " because IPv6 is disabled";
+               *error_message = fmtgettext("Unable to connect to %s because IPv6 is disabled", connect_address.serializeString().c_str());
                errorstream << *error_message << std::endl;
                return false;
        }
 
-       client = new Client(start_data.name.c_str(),
-                       start_data.password, start_data.address,
-                       *draw_control, texture_src, shader_src,
-                       itemdef_manager, nodedef_manager, sound, eventmgr,
-                       m_rendering_engine, connect_address.isIPv6(), m_game_ui.get());
+       try {
+               client = new Client(start_data.name.c_str(),
+                               start_data.password, start_data.address,
+                               *draw_control, texture_src, shader_src,
+                               itemdef_manager, nodedef_manager, sound, eventmgr,
+                               m_rendering_engine, connect_address.isIPv6(), m_game_ui.get());
+               client->migrateModStorage();
+       } catch (const BaseException &e) {
+               *error_message = fmtgettext("Error creating client: %s", e.what());
+               errorstream << *error_message << std::endl;
+               return false;
+       }
 
        client->m_simple_singleplayer_mode = simple_singleplayer_mode;
 
        infostream << "Connecting to server at ";
-       connect_address.print(&infostream);
+       connect_address.print(infostream);
        infostream << std::endl;
 
        client->connect(connect_address,
@@ -696,15 +699,15 @@ bool Game::connectToServer(const GameStartData &start_data,
        try {
                input->clear();
 
-               FpsControl fps_control = { 0 };
+               FpsControl fps_control;
                f32 dtime;
                f32 wait_time = 0; // in seconds
 
-               fps_control.last_time = m_rendering_engine->get_timer_time();
+               fps_control.reset();
 
                while (m_rendering_engine->run()) {
 
-                       limitFps(&fps_control, &dtime);
+                       fps_control.limit(device, &dtime);
 
                        // Update client and server
                        client->step(dtime);
@@ -723,8 +726,7 @@ bool Game::connectToServer(const GameStartData &start_data,
                                break;
 
                        if (client->accessDenied()) {
-                               *error_message = "Access denied. Reason: "
-                                               + client->accessDeniedReason();
+                               *error_message = fmtgettext("Access denied. Reason: %s", client->accessDeniedReason().c_str());
                                *reconnect_requested = client->reconnectRequested();
                                errorstream << *error_message << std::endl;
                                break;
@@ -750,7 +752,7 @@ bool Game::connectToServer(const GameStartData &start_data,
                                wait_time += dtime;
                                // Only time out if we aren't waiting for the server we started
                                if (!start_data.address.empty() && wait_time > 10) {
-                                       *error_message = "Connection timed out.";
+                                       *error_message = gettext("Connection timed out.");
                                        errorstream << *error_message << std::endl;
                                        break;
                                }
@@ -772,14 +774,14 @@ bool Game::getServerContent(bool *aborted)
 {
        input->clear();
 
-       FpsControl fps_control = { 0 };
+       FpsControl fps_control;
        f32 dtime; // in seconds
 
-       fps_control.last_time = m_rendering_engine->get_timer_time();
+       fps_control.reset();
 
        while (m_rendering_engine->run()) {
 
-               limitFps(&fps_control, &dtime);
+               fps_control.limit(device, &dtime);
 
                // Update client and server
                client->step(dtime);
@@ -798,7 +800,7 @@ bool Game::getServerContent(bool *aborted)
                        return false;
 
                if (client->getState() < LC_Init) {
-                       *error_message = "Client disconnected";
+                       *error_message = gettext("Client disconnected");
                        errorstream << *error_message << std::endl;
                        return false;
                }
@@ -880,8 +882,7 @@ inline void Game::updateInteractTimers(f32 dtime)
 inline bool Game::checkConnection()
 {
        if (client->accessDenied()) {
-               *error_message = "Access denied. Reason: "
-                               + client->accessDeniedReason();
+               *error_message = fmtgettext("Access denied. Reason: %s", client->accessDeniedReason().c_str());
                *reconnect_requested = client->reconnectRequested();
                errorstream << *error_message << std::endl;
                return false;
@@ -936,17 +937,16 @@ void Game::processQueues()
 
 void Game::updateDebugState()
 {
-       bool has_basic_debug = client->checkPrivilege("basic_debug");
+       LocalPlayer *player = client->getEnv().getLocalPlayer();
        bool has_debug = client->checkPrivilege("debug");
+       bool has_basic_debug = has_debug || (player->hud_flags & HUD_FLAG_BASIC_DEBUG);
 
        if (m_game_ui->m_flags.show_basic_debug) {
-               if (!has_basic_debug) {
+               if (!has_basic_debug)
                        m_game_ui->m_flags.show_basic_debug = false;
-               }
        } else if (m_game_ui->m_flags.show_minimal_debug) {
-               if (has_basic_debug) {
+               if (has_basic_debug)
                        m_game_ui->m_flags.show_basic_debug = true;
-               }
        }
        if (!has_basic_debug)
                hud->disableBlockBounds();
@@ -977,10 +977,10 @@ void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times,
        }
 
        // Update update graphs
-       g_profiler->graphAdd("Time non-rendering [ms]",
+       g_profiler->graphAdd("Time non-rendering [us]",
                draw_times.busy_time - stats.drawtime);
 
-       g_profiler->graphAdd("Sleep [ms]", draw_times.sleep_time);
+       g_profiler->graphAdd("Sleep [us]", draw_times.sleep_time);
        g_profiler->graphAdd("FPS", 1.0f / dtime);
 }
 
@@ -1013,9 +1013,9 @@ void Game::updateStats(RunStats *stats, const FpsControl &draw_times,
        /* Busytime average and jitter calculation
         */
        jp = &stats->busy_time_jitter;
-       jp->avg = jp->avg + draw_times.busy_time * 0.02;
+       jp->avg = jp->avg + draw_times.getBusyMs() * 0.02;
 
-       jitter = draw_times.busy_time - jp->avg;
+       jitter = draw_times.getBusyMs() - jp->avg;
 
        if (jitter > jp->max)
                jp->max = jitter;
@@ -1052,6 +1052,7 @@ void Game::processUserInput(f32 dtime)
        else if (g_touchscreengui) {
                /* on touchscreengui step may generate own input events which ain't
                 * what we want in case we just did clear them */
+               g_touchscreengui->show();
                g_touchscreengui->step(dtime);
        }
 #endif
@@ -1290,15 +1291,22 @@ void Game::openInventory()
        InventoryLocation inventoryloc;
        inventoryloc.setCurrentPlayer();
 
-       if (!client->modsLoaded()
-                       || !client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) {
-               TextDest *txt_dst = new TextDestPlayerInventory(client);
-               auto *&formspec = m_game_ui->updateFormspec("");
-               GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
-                       &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound);
+       if (client->modsLoaded() && client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) {
+               delete fs_src;
+               return;
+       }
 
-               formspec->setFormSpec(fs_src->getForm(), inventoryloc);
+       if (fs_src->getForm().empty()) {
+               delete fs_src;
+               return;
        }
+
+       TextDest *txt_dst = new TextDestPlayerInventory(client);
+       auto *&formspec = m_game_ui->updateFormspec("");
+       GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
+               &input->joystick, fs_src, txt_dst, client->getFormspecPrepend(), sound);
+
+       formspec->setFormSpec(fs_src->getForm(), inventoryloc);
 }
 
 void Game::openEnderchest()
@@ -1398,7 +1406,7 @@ void Game::toggleFast()
                m_game_ui->showTranslatedStatusText("Fast mode disabled");
        }
 
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        m_cache_hold_aux1 = fast_move && has_fast_privs;
 #endif
 }
@@ -1469,27 +1477,27 @@ void Game::toggleCinematic()
 
 void Game::toggleBlockBounds()
 {
-       if (client->checkPrivilege("basic_debug")) {
-               enum Hud::BlockBoundsMode newmode = hud->toggleBlockBounds();
-               switch (newmode) {
-                       case Hud::BLOCK_BOUNDS_OFF:
-                               m_game_ui->showTranslatedStatusText("Block bounds hidden");
-                               break;
-                       case Hud::BLOCK_BOUNDS_CURRENT:
-                               m_game_ui->showTranslatedStatusText("Block bounds shown for current block");
-                               break;
-                       case Hud::BLOCK_BOUNDS_NEAR:
-                               m_game_ui->showTranslatedStatusText("Block bounds shown for nearby blocks");
-                               break;
-                       case Hud::BLOCK_BOUNDS_MAX:
-                               m_game_ui->showTranslatedStatusText("Block bounds shown for all blocks");
-                               break;
-                       default:
-                               break;
-               }
-
-       } else {
-               m_game_ui->showTranslatedStatusText("Can't show block bounds (need 'basic_debug' privilege)");
+       LocalPlayer *player = client->getEnv().getLocalPlayer();
+       if (!(client->checkPrivilege("debug") || (player->hud_flags & HUD_FLAG_BASIC_DEBUG))) {
+               m_game_ui->showTranslatedStatusText("Can't show block bounds (disabled by mod or game)");
+               return;
+       }
+       enum Hud::BlockBoundsMode newmode = hud->toggleBlockBounds();
+       switch (newmode) {
+               case Hud::BLOCK_BOUNDS_OFF:
+                       m_game_ui->showTranslatedStatusText("Block bounds hidden");
+                       break;
+               case Hud::BLOCK_BOUNDS_CURRENT:
+                       m_game_ui->showTranslatedStatusText("Block bounds shown for current block");
+                       break;
+               case Hud::BLOCK_BOUNDS_NEAR:
+                       m_game_ui->showTranslatedStatusText("Block bounds shown for nearby blocks");
+                       break;
+               case Hud::BLOCK_BOUNDS_MAX:
+                       m_game_ui->showTranslatedStatusText("Block bounds shown for all blocks");
+                       break;
+               default:
+                       break;
        }
 }
 
@@ -1556,6 +1564,9 @@ void Game::toggleFog()
 
 void Game::toggleDebug()
 {
+       LocalPlayer *player = client->getEnv().getLocalPlayer();
+       bool has_debug = client->checkPrivilege("debug");
+       bool has_basic_debug = has_debug || (player->hud_flags & HUD_FLAG_BASIC_DEBUG);
        // Initial: No debug info
        // 1x toggle: Debug text
        // 2x toggle: Debug text with profiler graph
@@ -1565,26 +1576,23 @@ void Game::toggleDebug()
        // The debug text can be in 2 modes: minimal and basic.
        // * Minimal: Only technical client info that not gameplay-relevant
        // * Basic: Info that might give gameplay advantage, e.g. pos, angle
-       // Basic mode is used when player has "basic_debug" priv,
+       // Basic mode is used when player has the debug HUD flag set,
        // otherwise the Minimal mode is used.
        if (!m_game_ui->m_flags.show_minimal_debug) {
                m_game_ui->m_flags.show_minimal_debug = true;
-               if (client->checkPrivilege("basic_debug")) {
+               if (has_basic_debug)
                        m_game_ui->m_flags.show_basic_debug = true;
-               }
                m_game_ui->m_flags.show_profiler_graph = false;
                draw_control->show_wireframe = false;
                m_game_ui->showTranslatedStatusText("Debug info shown");
        } else if (!m_game_ui->m_flags.show_profiler_graph && !draw_control->show_wireframe) {
-               if (client->checkPrivilege("basic_debug")) {
+               if (has_basic_debug)
                        m_game_ui->m_flags.show_basic_debug = true;
-               }
                m_game_ui->m_flags.show_profiler_graph = true;
                m_game_ui->showTranslatedStatusText("Profiler graph shown");
        } else if (!draw_control->show_wireframe && client->checkPrivilege("debug")) {
-               if (client->checkPrivilege("basic_debug")) {
+               if (has_basic_debug)
                        m_game_ui->m_flags.show_basic_debug = true;
-               }
                m_game_ui->m_flags.show_profiler_graph = false;
                draw_control->show_wireframe = true;
                m_game_ui->showTranslatedStatusText("Wireframe shown");
@@ -1593,7 +1601,7 @@ void Game::toggleDebug()
                m_game_ui->m_flags.show_basic_debug = false;
                m_game_ui->m_flags.show_profiler_graph = false;
                draw_control->show_wireframe = false;
-               if (client->checkPrivilege("debug")) {
+               if (has_debug) {
                        m_game_ui->showTranslatedStatusText("Debug info, profiler graph, and wireframe hidden");
                } else {
                        m_game_ui->showTranslatedStatusText("Debug info and profiler graph hidden");
@@ -1755,6 +1763,10 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
        //TimeTaker tt("update player control", NULL, PRECISION_NANO);
 
        PlayerControl control(
+               isKeyDown(KeyType::FORWARD),
+               isKeyDown(KeyType::BACKWARD),
+               isKeyDown(KeyType::LEFT),
+               isKeyDown(KeyType::RIGHT),
                isKeyDown(KeyType::JUMP) || player->getAutojump(),
                isKeyDown(KeyType::AUX1),
                isKeyDown(KeyType::SNEAK),
@@ -1774,10 +1786,10 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
                control.movement_direction = 0.0f;
        }
 
-#ifdef ANDROID
-       /* For Android, simulate holding down AUX1 (fast move) if the user has
+#ifdef HAVE_TOUCHSCREENGUI
+       /* For touch, simulate holding down AUX1 (fast move) if the user has
         * the fast_move setting toggled on. If there is an aux1 key defined for
-        * Android then its meaning is inverted (i.e. holding aux1 means walk and
+        * touch then its meaning is inverted (i.e. holding aux1 means walk and
         * not fast)
         */
        if (m_cache_hold_aux1) {
@@ -1785,39 +1797,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
        }
 #endif
 
-       u32 keypress_bits = (
-                       ( (u32)(control.jump  & 0x1) << 4) |
-                       ( (u32)(control.aux1  & 0x1) << 5) |
-                       ( (u32)(control.sneak & 0x1) << 6) |
-                       ( (u32)(control.dig   & 0x1) << 7) |
-                       ( (u32)(control.place & 0x1) << 8) |
-                       ( (u32)(control.zoom  & 0x1) << 9)
-               );
-
-       // Set direction keys to ensure mod compatibility
-       if (control.movement_speed > 0.001f) {
-               float absolute_direction;
-
-               // Check in original orientation (absolute value indicates forward / backward)
-               absolute_direction = abs(control.movement_direction);
-               if (absolute_direction < (3.0f / 8.0f * M_PI))
-                       keypress_bits |= (u32)(0x1 << 0); // Forward
-               if (absolute_direction > (5.0f / 8.0f * M_PI))
-                       keypress_bits |= (u32)(0x1 << 1); // Backward
-
-               // Rotate entire coordinate system by 90 degrees (absolute value indicates left / right)
-               absolute_direction = control.movement_direction + M_PI_2;
-               if (absolute_direction >= M_PI)
-                       absolute_direction -= 2 * M_PI;
-               absolute_direction = abs(absolute_direction);
-               if (absolute_direction < (3.0f / 8.0f * M_PI))
-                       keypress_bits |= (u32)(0x1 << 2); // Left
-               if (absolute_direction > (5.0f / 8.0f * M_PI))
-                       keypress_bits |= (u32)(0x1 << 3); // Right
-       }
-
        client->setPlayerControl(control);
-       player->keyPressed = keypress_bits;
 
        //tt.stop();
 }
@@ -2172,7 +2152,7 @@ void Game::handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam)
 void Game::handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam)
 {
        sky->setStarsVisible(event->star_params->visible);
-       sky->setStarCount(event->star_params->count, false);
+       sky->setStarCount(event->star_params->count);
        sky->setStarColor(event->star_params->starcolor);
        sky->setStarScale(event->star_params->scale);
        delete event->star_params;
@@ -2209,7 +2189,7 @@ void Game::processClientEvents(CameraOrientation *cam)
        }
 }
 
-void Game::updateChat(f32 dtime, const v2u32 &screensize)
+void Game::updateChat(f32 dtime)
 {
        // Get new messages from error log buffer
        while (!m_chat_log_buf.empty())
@@ -2225,11 +2205,17 @@ void Game::updateChat(f32 dtime, const v2u32 &screensize)
        chat_backend->step(dtime);
 
        // Display all messages in a static text element
-       m_game_ui->setChatText(chat_backend->getRecentChat(),
-               chat_backend->getRecentBuffer().getLineCount());
+       auto &buf = chat_backend->getRecentBuffer();
+       if (buf.getLinesModified()) {
+               buf.resetLinesModified();
+               m_game_ui->setChatText(chat_backend->getRecentChat(), buf.getLineCount());
+       }
+
+       // Make sure that the size is still correct
+       m_game_ui->updateChatSize();
 }
 
-void Game::updateCamera(u32 busy_time, f32 dtime)
+void Game::updateCamera(f32 dtime)
 {
        LocalPlayer *player = client->getEnv().getLocalPlayer();
 
@@ -2259,7 +2245,7 @@ void Game::updateCamera(u32 busy_time, f32 dtime)
        float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
 
        tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0);
-       camera->update(player, dtime, busy_time / 1000.0f, tool_reload_ratio);
+       camera->update(player, dtime, tool_reload_ratio);
        camera->step(dtime);
 
        v3f camera_position = camera->getPosition();
@@ -2333,7 +2319,7 @@ void Game::updateSound(f32 dtime)
 }
 
 
-void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
+void Game::processPlayerInteraction(f32 dtime, bool show_hud)
 {
        LocalPlayer *player = client->getEnv().getLocalPlayer();
 
@@ -2391,10 +2377,12 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
                        !runData.btn_down_for_dig,
                        camera_offset);
 
-       if (pointed != runData.pointed_old) {
+       if (pointed != runData.pointed_old)
                infostream << "Pointing at " << pointed.dump() << std::endl;
-               hud->updateSelectionMesh(camera_offset);
-       }
+
+       // Note that updating the selection mesh every frame is not particularly efficient,
+       // but the halo rendering code is already inefficient so there's no point in optimizing it here
+       hud->updateSelectionMesh(camera_offset);
 
        // Allow digging again if button is not pressed
        if (runData.digging_blocked && !isKeyDown(KeyType::DIG))
@@ -2455,7 +2443,9 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
                handlePointingAtNode(pointed, selected_item, hand_item, dtime);
        } else if (pointed.type == POINTEDTHING_OBJECT) {
                v3f player_position  = player->getPosition();
-               handlePointingAtObject(pointed, tool_item, player_position, show_debug);
+               bool basic_debug_allowed = client->checkPrivilege("debug") || (player->hud_flags & HUD_FLAG_BASIC_DEBUG);
+               handlePointingAtObject(pointed, tool_item, player_position,
+                               m_game_ui->m_flags.show_basic_debug && basic_debug_allowed);
        } else if (isKeyDown(KeyType::DIG)) {
                // When button is held down in air, show continuous animation
                runData.punching = true;
@@ -2614,9 +2604,8 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
        } else {
                MapNode n = map.getNode(nodepos);
 
-               if (nodedef_manager->get(n).tiledef[0].name == "unknown_node.png") {
-                       m_game_ui->setInfoText(L"Unknown node: " +
-                               utf8_to_wide(nodedef_manager->get(n).name));
+               if (nodedef_manager->get(n).name == "unknown") {
+                       m_game_ui->setInfoText(L"Unknown node");
                }
        }
 
@@ -2904,7 +2893,8 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
        // cheat detection.
        // Get digging parameters
        DigParams params = getDigParams(nodedef_manager->get(n).groups,
-                       &selected_item.getToolCapabilities(itemdef_manager));
+                       &selected_item.getToolCapabilities(itemdef_manager),
+                       selected_item.wear);
 
        // If can't dig, try hand
        if (!params.diggable) {
@@ -3155,12 +3145,28 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        }
 
        /*
-               Get chat messages from client
+               Damage camera tilt
        */
+       if (player->hurt_tilt_timer > 0.0f) {
+               player->hurt_tilt_timer -= dtime * 6.0f;
 
-       v2u32 screensize = driver->getScreenSize();
+               if (player->hurt_tilt_timer < 0.0f || g_settings->getBool("no_hurt_cam"))
+                       player->hurt_tilt_strength = 0.0f;
+       }
+
+       /*
+               Update minimap pos and rotation
+       */
+       if (mapper && m_game_ui->m_flags.show_hud) {
+               mapper->setPos(floatToInt(player->getPosition(), BS));
+               mapper->setAngle(player->getYaw());
+       }
+
+       /*
+               Get chat messages from client
+       */
 
-       updateChat(dtime, screensize);
+       updateChat(dtime);
 
        /*
                Inventory
@@ -3187,8 +3193,8 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        v3f camera_direction = camera->getDirection();
        if (runData.update_draw_list_timer >= update_draw_list_delta
                        || runData.update_draw_list_last_cam_dir.getDistanceFrom(camera_direction) > 0.2
-                       || m_camera_offset_changed) {
-
+                       || m_camera_offset_changed
+                       || client->getEnv().getClientMap().needsUpdateDrawList()) {
                runData.update_draw_list_timer = 0;
                client->getEnv().getClientMap().updateDrawList();
                runData.update_draw_list_last_cam_dir = camera_direction;
@@ -3229,11 +3235,11 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        } while (false);
 
        /*
-               Drawing begins
+               ==================== Drawing begins ====================
        */
-       const video::SColor &skycolor = sky->getSkyColor();
+       const video::SColor skycolor = sky->getSkyColor();
 
-       TimeTaker tt_draw("Draw scene");
+       TimeTaker tt_draw("Draw scene", nullptr, PRECISION_MICRO);
        driver->beginScene(true, true, skycolor);
 
        bool draw_wield_tool = (m_game_ui->m_flags.show_hud &&
@@ -3254,6 +3260,8 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        /*
                Profiler graph
        */
+       v2u32 screensize = driver->getScreenSize();
+
        if (m_game_ui->m_flags.show_profiler_graph)
                graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont());
 
@@ -3278,27 +3286,10 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                runData.damage_flash -= 384.0f * dtime;
        }
 
-       /*
-               Damage camera tilt
-       */
-       if (player->hurt_tilt_timer > 0.0f) {
-               player->hurt_tilt_timer -= dtime * 6.0f;
-
-               if (player->hurt_tilt_timer < 0.0f || g_settings->getBool("no_hurt_cam"))
-                       player->hurt_tilt_strength = 0.0f;
-       }
-
-       /*
-               Update minimap pos and rotation
-       */
-       if (mapper && m_game_ui->m_flags.show_hud) {
-               mapper->setPos(floatToInt(player->getPosition(), BS));
-               mapper->setAngle(player->getYaw());
-       }
-
        /*
                End scene
        */
+#if IRRLICHT_VERSION_MT_REVISION < 5
        if (++m_reset_HW_buffer_counter > 500) {
                /*
                  Periodically remove all mesh HW buffers.
@@ -3320,11 +3311,13 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                driver->removeAllHardwareBuffers();
                m_reset_HW_buffer_counter = 0;
        }
+#endif
+
        driver->endScene();
 
        stats->drawtime = tt_draw.stop(true);
-       g_profiler->avg("Game::updateFrame(): draw scene [ms]", stats->drawtime);
-       g_profiler->graphAdd("Update frame [ms]", tt_update.stop(true));
+       g_profiler->graphAdd("Draw scene [us]", stats->drawtime);
+       g_profiler->avg("Game::updateFrame(): update frame [ms]", tt_update.stop(true));
 }
 
 /* Log times and stuff for visualization */
@@ -3346,7 +3339,12 @@ void Game::updateShadows()
 
        float in_timeofday = fmod(runData.time_of_day_smooth, 1.0f);
 
-       float timeoftheday = fmod(getWickedTimeOfDay(in_timeofday) + 0.75f, 0.5f) + 0.25f;
+       float timeoftheday = getWickedTimeOfDay(in_timeofday);
+       bool is_day = timeoftheday > 0.25 && timeoftheday < 0.75;
+       bool is_shadow_visible = is_day ? sky->getSunVisible() : sky->getMoonVisible();
+       shadow->setShadowIntensity(is_shadow_visible ? client->getEnv().getLocalPlayer()->getLighting().shadow_intensity : 0.0f);
+
+       timeoftheday = fmod(timeoftheday + 0.75f, 0.5f) + 0.25f;
        const float offset_constant = 10000.0f;
 
        v3f light(0.0f, 0.0f, -1.0f);
@@ -3368,47 +3366,46 @@ void Game::updateShadows()
  Misc
  ****************************************************************************/
 
-/* On some computers framerate doesn't seem to be automatically limited
- */
-inline void Game::limitFps(FpsControl *fps_timings, f32 *dtime)
+void FpsControl::reset()
 {
-       // not using getRealTime is necessary for wine
-       device->getTimer()->tick(); // Maker sure device time is up-to-date
-       u32 time = device->getTimer()->getTime();
-       u32 last_time = fps_timings->last_time;
-
-       if (time > last_time)  // Make sure time hasn't overflowed
-               fps_timings->busy_time = time - last_time;
-       else
-               fps_timings->busy_time = 0;
+       last_time = porting::getTimeUs();
+}
 
-       u32 frametime_min = 1000 / (
+/*
+ * On some computers framerate doesn't seem to be automatically limited
+ */
+void FpsControl::limit(IrrlichtDevice *device, f32 *dtime)
+{
+       const u64 frametime_min = 1000000.0f / (
                device->isWindowFocused() && !g_menumgr.pausesGame()
                        ? g_settings->getFloat("fps_max")
                        : g_settings->getFloat("fps_max_unfocused"));
 
-       if (fps_timings->busy_time < frametime_min) {
-               fps_timings->sleep_time = frametime_min - fps_timings->busy_time;
-               device->sleep(fps_timings->sleep_time);
+       u64 time = porting::getTimeUs();
+
+       if (time > last_time) // Make sure time hasn't overflowed
+               busy_time = time - last_time;
+       else
+               busy_time = 0;
+
+       if (busy_time < frametime_min) {
+               sleep_time = frametime_min - busy_time;
+               if (sleep_time > 1000)
+                       sleep_ms(sleep_time / 1000);
        } else {
-               fps_timings->sleep_time = 0;
+               sleep_time = 0;
        }
 
-       /* Get the new value of the device timer. Note that device->sleep() may
-        * not sleep for the entire requested time as sleep may be interrupted and
-        * therefore it is arguably more accurate to get the new time from the
-        * device rather than calculating it by adding sleep_time to time.
-        */
-
-       device->getTimer()->tick(); // Update device timer
-       time = device->getTimer()->getTime();
+       // Read the timer again to accurately determine how long we actually slept,
+       // rather than calculating it by adding sleep_time to time.
+       time = porting::getTimeUs();
 
-       if (time > last_time)  // Make sure last_time hasn't overflowed
-               *dtime = (time - last_time) / 1000.0;
+       if (time > last_time) // Make sure last_time hasn't overflowed
+               *dtime = (time - last_time) / 1000000.0f;
        else
                *dtime = 0;
 
-       fps_timings->last_time = time;
+       last_time = time;
 }
 
 void Game::showOverlayMessage(const char *msg, float dtime, int percent, bool draw_clouds)
@@ -3522,7 +3519,7 @@ void Game::showDeathFormspec()
 #define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name())
 void Game::showPauseMenu()
 {
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        static const std::string control_text = strgettext("Default Controls:\n"
                "No menu visible:\n"
                "- single tap: button activate\n"
@@ -3630,16 +3627,18 @@ void Game::showPauseMenu()
        if (simple_singleplayer_mode || address.empty()) {
                static const std::string on = strgettext("On");
                static const std::string off = strgettext("Off");
-               const std::string &damage = g_settings->getBool("enable_damage") ? on : off;
-               const std::string &creative = g_settings->getBool("creative_mode") ? on : off;
+               // Note: Status of enable_damage and creative_mode settings is intentionally
+               // NOT shown here because the game might roll its own damage system and/or do
+               // a per-player Creative Mode, in which case writing it here would mislead.
+               bool damage = g_settings->getBool("enable_damage");
                const std::string &announced = g_settings->getBool("server_announce") ? on : off;
-               os << strgettext("- Damage: ") << damage << "\n"
-                               << strgettext("- Creative Mode: ") << creative << "\n";
                if (!simple_singleplayer_mode) {
-                       const std::string &pvp = g_settings->getBool("enable_pvp") ? on : off;
-                       //~ PvP = Player versus Player
-                       os << strgettext("- PvP: ") << pvp << "\n"
-                                       << strgettext("- Public: ") << announced << "\n";
+                       if (damage) {
+                               const std::string &pvp = g_settings->getBool("enable_pvp") ? on : off;
+                               //~ PvP = Player versus Player
+                               os << strgettext("- PvP: ") << pvp << "\n";
+                       }
+                       os << strgettext("- Public: ") << announced << "\n";
                        std::string server_name = g_settings->get("server_name");
                        str_formspec_escape(server_name);
                        if (announced == on && !server_name.empty())
@@ -3698,14 +3697,15 @@ void the_game(bool *kill,
                }
 
        } catch (SerializationError &e) {
-               error_message = std::string("A serialization error occurred:\n")
-                               + e.what() + "\n\nThe server is probably "
-                               " running a different version of " PROJECT_NAME_C ".";
+               const std::string ver_err = fmtgettext("The server is probably running a different version of %s.", PROJECT_NAME_C);
+               error_message = strgettext("A serialization error occurred:") +"\n"
+                               + e.what() + "\n\n" + ver_err;
                errorstream << error_message << std::endl;
        } catch (ServerError &e) {
                error_message = e.what();
                errorstream << "ServerError: " << error_message << std::endl;
        } catch (ModError &e) {
+               // DO NOT TRANSLATE the `ModError`, it's used by ui.lua
                error_message = std::string("ModError: ") + e.what() +
                                strgettext("\nCheck debug.txt for details.");
                errorstream << error_message << std::endl;
index cb40d48904639613ef8ded00282b39137e02ca3a..0e5d0550d296b156acd1652b7bfcf205197b5a95 100644 (file)
@@ -86,7 +86,7 @@ struct Jitter {
 };
 
 struct RunStats {
-       u32 drawtime;
+       u64 drawtime; // (us)
 
        Jitter dtime_jitter, busy_time_jitter;
 };
@@ -584,7 +584,7 @@ class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactor
        }
 };
 
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
 #define SIZE_TAG "size[11,5.5]"
 #else
 #define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
@@ -596,7 +596,16 @@ class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactor
 const float object_hit_delay = 0.2;
 
 struct FpsControl {
-       u32 last_time, busy_time, sleep_time;
+       FpsControl() : last_time(0), busy_time(0), sleep_time(0) {}
+
+       void reset();
+
+       void limit(IrrlichtDevice *device, f32 *dtime);
+
+       u32 getBusyMs() const { return busy_time / 1000; }
+
+       // all values in microseconds (us)
+       u64 last_time, busy_time, sleep_time;
 };
 
 
@@ -726,9 +735,9 @@ class Game {
        void updatePlayerControl(const CameraOrientation &cam);
        void step(f32 *dtime);
        void processClientEvents(CameraOrientation *cam);
-       void updateCamera(u32 busy_time, f32 dtime);
+       void updateCamera(f32 dtime);
        void updateSound(f32 dtime);
-       void processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug);
+       void processPlayerInteraction(f32 dtime, bool show_hud);
        /*!
         * Returns the object or node the player is pointing at.
         * Also updates the selected thing in the Hud.
@@ -757,8 +766,6 @@ class Game {
        void updateShadows();
 
        // Misc
-       void limitFps(FpsControl *fps_timings, f32 *dtime);
-
        void showOverlayMessage(const char *msg, float dtime, int percent,
                        bool draw_clouds = true);
 
@@ -807,7 +814,7 @@ class Game {
                CameraOrientation *cam);
        void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
 
-       void updateChat(f32 dtime, const v2u32 &screensize);
+       void updateChat(f32 dtime);
 
        bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item,
                const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
@@ -904,12 +911,17 @@ class Game {
 
        bool m_does_lost_focus_pause_game = false;
 
-       CameraOrientation cam_view_target  = { 0 };
-       CameraOrientation cam_view  = { 0 };
+       CameraOrientation cam_view_target = {}; // added by dragonfireclient
+       CameraOrientation cam_view  = {};       // added by dragonfireclient
 
+#if IRRLICHT_VERSION_MT_REVISION < 5
        int m_reset_HW_buffer_counter = 0;
-#ifdef __ANDROID__
+#endif
+
+#ifdef HAVE_TOUCHSCREENGUI
        bool m_cache_hold_aux1;
+#endif
+#ifdef __ANDROID__
        bool m_android_chat_open;
 #endif
 };
index 66a006ea196cae71925725bb84105933e0897462..54be24ae2ac6fd7fc65fef0a31f6bb8bbb112148 100644 (file)
@@ -124,16 +124,16 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
 
        // Minimal debug text must only contain info that can't give a gameplay advantage
        if (m_flags.show_minimal_debug) {
-               static float drawtime_avg = 0;
-               drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
-               u16 fps = 1.0 / stats.dtime_jitter.avg;
+               const u16 fps = 1.0 / stats.dtime_jitter.avg;
+               m_drawtime_avg *= 0.95f;
+               m_drawtime_avg += 0.05f * (stats.drawtime / 1000);
 
                std::ostringstream os(std::ios_base::binary);
                os << std::fixed
                        << PROJECT_NAME_C " " << g_version_hash
                        << " | FPS: " << fps
                        << std::setprecision(0)
-                       << " | drawtime: " << drawtime_avg << "ms"
+                       << " | drawtime: " << m_drawtime_avg << "ms"
                        << std::setprecision(1)
                        << " | dtime jitter: "
                        << (stats.dtime_jitter.max_fraction * 100.0) << "%"
@@ -171,9 +171,13 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
                        const NodeDefManager *nodedef = client->getNodeDefManager();
                        MapNode n = map.getNode(pointed_old.node_undersurface);
 
-                       if (n.getContent() != CONTENT_IGNORE && nodedef->get(n).name != "unknown") {
-                               os << ", pointed: " << nodedef->get(n).name
-                                       << ", param2: " << (u64) n.getParam2();
+                       if (n.getContent() != CONTENT_IGNORE) {
+                               if (nodedef->get(n).name == "unknown") {
+                                       os << ", pointed: <unknown node>";
+                               } else {
+                                       os << ", pointed: " << nodedef->get(n).name;
+                               }
+                               os << ", param2: " << (u64) n.getParam2();
                        }
                }
 
@@ -229,7 +233,6 @@ void GameUI::initFlags()
 {
        m_flags = GameUI::Flags();
        m_flags.show_minimal_debug = g_settings->getBool("show_debug");
-       m_flags.show_basic_debug = false;
 }
 
 void GameUI::showMinimap(bool show)
@@ -246,7 +249,13 @@ void GameUI::showTranslatedStatusText(const char *str)
 
 void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count)
 {
+       setStaticText(m_guitext_chat, chat_text);
 
+       m_recent_chat_count = recent_chat_count;
+}
+
+void GameUI::updateChatSize()
+{
        // Update gui element size and position
 
        const v2u32 &window_size = RenderingEngine::getWindowSize();
@@ -258,15 +267,15 @@ void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count)
        if (m_flags.show_basic_debug)
                chat_y += g_fontengine->getLineHeight();
 
-       core::rect<s32> chat_size(10, chat_y,
-               window_size.X - 20, 0);
+       core::rect<s32> chat_size(10, chat_y, window_size.X - 20, 0);
        chat_size.LowerRightCorner.Y = std::min((s32)window_size.Y,
-               m_guitext_chat->getTextHeight() + chat_y);
+                       m_guitext_chat->getTextHeight() + chat_y);
 
-       m_guitext_chat->setRelativePosition(chat_size);
-       setStaticText(m_guitext_chat, chat_text);
+       if (chat_size == m_current_chat_size)
+               return;
+       m_current_chat_size = chat_size;
 
-       m_recent_chat_count = recent_chat_count;
+       m_guitext_chat->setRelativePosition(chat_size);
 }
 
 void GameUI::updateProfiler()
index 5404643e2321e65a18f8152eaf87e83612d2491b..e22be068b2ced66d30cf27f85878390eef936ae7 100644 (file)
@@ -85,11 +85,12 @@ class GameUI
        void showTranslatedStatusText(const char *str);
        inline void clearStatusText() { m_statustext.clear(); }
 
-       const bool isChatVisible()
+       bool isChatVisible()
        {
                return m_flags.show_chat && m_recent_chat_count != 0 && m_profiler_current_page == 0;
        }
        void setChatText(const EnrichedString &chat_text, u32 recent_chat_count);
+       void updateChatSize();
 
        void updateProfiler();
 
@@ -111,6 +112,8 @@ class GameUI
 private:
        Flags m_flags;
 
+       float m_drawtime_avg = 0;
+
        gui::IGUIStaticText *m_guitext = nullptr;  // First line of debug text
        gui::IGUIStaticText *m_guitext2 = nullptr; // Second line of debug text
        gui::IGUIStaticText *m_guitext_coords = nullptr;
@@ -125,6 +128,7 @@ class GameUI
 
        gui::IGUIStaticText *m_guitext_chat = nullptr; // Chat text
        u32 m_recent_chat_count = 0;
+       core::rect<s32> m_current_chat_size{0, 0, 0, 0};
 
        gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text
        u8 m_profiler_current_page = 0;
index 232219237be2bdcab84745022b29f35cd0c358d2..de122becf218942737f78109727c67866cb60de7 100644 (file)
@@ -43,6 +43,10 @@ void guiScalingCache(const io::path &key, video::IVideoDriver *driver, video::II
 {
        if (!g_settings->getBool("gui_scaling_filter"))
                return;
+
+       if (g_imgCache.find(key) != g_imgCache.end())
+               return; // Already cached.
+
        video::IImage *copied = driver->createImage(value->getColorFormat(),
                        value->getDimension());
        value->copyTo(copied);
@@ -90,14 +94,16 @@ video::ITexture *guiScalingResizeCached(video::IVideoDriver *driver,
        io::path scalename = origname + "@guiScalingFilter:" + rectstr;
 
        // Search for existing scaled texture.
-       video::ITexture *scaled = g_txrCache[scalename];
+       auto it_txr = g_txrCache.find(scalename);
+       video::ITexture *scaled = (it_txr != g_txrCache.end()) ? it_txr->second : nullptr;
        if (scaled)
                return scaled;
 
        // Try to find the texture converted to an image in the cache.
        // If the image was not found, try to extract it from the texture.
-       video::IImage* srcimg = g_imgCache[origname];
-       if (srcimg == NULL) {
+       auto it_img = g_imgCache.find(origname);
+       video::IImage *srcimg = (it_img != g_imgCache.end()) ? it_img->second : nullptr;
+       if (!srcimg) {
                if (!g_settings->getBool("gui_scaling_filter_txr2img"))
                        return src;
                srcimg = driver->createImageFromData(src->getColorFormat(),
index 3f687b698dcb602ebd0f07fd8dd3767725be3719..d5debecfbb71ade34c6485f78609a4ed3ef925ea 100644 (file)
@@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "client/hud.h"
+#include <string>
+#include <iostream>
 #include <cmath>
 #include "settings.h"
 #include "util/numeric.h"
@@ -222,6 +224,7 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
 }
 
 //NOTE: selectitem = 0 -> no selected; selectitem 1-based
+// mainlist can be NULL, but draw the frame anyway.
 void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
                s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
 {
@@ -269,7 +272,8 @@ void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
 
        // Draw items
        core::rect<s32> imgrect(0, 0, m_hotbar_imagesize, m_hotbar_imagesize);
-       for (s32 i = inv_offset; i < itemcount && (size_t)i < mainlist->getSize(); i++) {
+       const s32 list_size = mainlist ? mainlist->getSize() : 0;
+       for (s32 i = inv_offset; i < itemcount && i < list_size; i++) {
                s32 fullimglen = m_hotbar_imagesize + m_padding * 2;
 
                v2s32 steppos;
@@ -377,15 +381,19 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
                                std::wstring text = unescape_translate(utf8_to_wide(e->text));
                                core::dimension2d<u32> textsize = textfont->getDimension(text.c_str());
 
-                               v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
-                                            (e->align.Y - 1.0) * (textsize.Height / 2));
+                               v2s32 offset(0, (e->align.Y - 1.0) * (textsize.Height / 2));
                                core::rect<s32> size(0, 0, e->scale.X * m_scale_factor,
-                                                    text_height * e->scale.Y * m_scale_factor);
+                                               text_height * e->scale.Y * m_scale_factor);
                                v2s32 offs(e->offset.X * m_scale_factor,
-                                          e->offset.Y * m_scale_factor);
-
+                                               e->offset.Y * m_scale_factor);
+                               std::wstringstream wss(text);
+                               std::wstring line;
+                               while (std::getline(wss, line, L'\n'))
                                {
-                                       textfont->draw(text.c_str(), size + pos + offset + offs, color);
+                                       core::dimension2d<u32> linesize = textfont->getDimension(line.c_str());
+                                       v2s32 line_offset((e->align.X - 1.0) * (linesize.Width / 2), 0);
+                                       textfont->draw(line.c_str(), size + pos + offset + offs + line_offset, color);
+                                       offset.Y += linesize.Height;
                                }
                                break; }
                        case HUD_ELEM_STATBAR: {
@@ -395,6 +403,8 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
                                break; }
                        case HUD_ELEM_INVENTORY: {
                                InventoryList *inv = inventory->getList(e->text);
+                               if (!inv)
+                                       warningstream << "HUD: Unknown inventory list. name=" << e->text << std::endl;
                                drawItems(pos, v2s32(e->offset.X, e->offset.Y), e->number, 0,
                                        inv, e->item, e->dir);
                                break; }
@@ -666,7 +676,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
        // Rectangles for 1/2 the "off state" texture
        core::rect<s32> srchalfrect2, dsthalfrect2;
 
-       if (count % 2 == 1) {
+       if (count % 2 == 1 || maxcount % 2 == 1) {
                // Need to draw halves: Calculate rectangles
                srchalfrect  = calculate_clipping_rect(srcd, steppos);
                dsthalfrect  = calculate_clipping_rect(dstd, steppos);
@@ -701,7 +711,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
                }
        }
 
-       if (stat_texture_bg && maxcount > count / 2) {
+       if (stat_texture_bg && maxcount > count) {
                // Draw "off state" textures
                s32 start_offset;
                if (count % 2 == 1)
@@ -721,8 +731,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
 
                if (maxcount % 2 == 1) {
                        draw2DImageFilterScaled(driver, stat_texture_bg,
-                                       dsthalfrect + p, srchalfrect,
-                                       NULL, colors, true);
+                               dsthalfrect + p, srchalfrect, NULL, colors, true);
                }
        }
 }
@@ -1001,11 +1010,19 @@ void drawItemStack(
 
        bool draw_overlay = false;
 
+       bool has_mesh = false;
+       ItemMesh *imesh;
+
+       core::rect<s32> viewrect = rect;
+       if (clip != nullptr)
+               viewrect.clipAgainst(*clip);
+
        // Render as mesh if animated or no inventory image
        if ((enable_animations && rotation_kind < IT_ROT_NONE) || def.inventory_image.empty()) {
-               ItemMesh *imesh = client->idef()->getWieldMesh(def.name, client);
-               if (!imesh || !imesh->mesh)
-                       return;
+               imesh = client->idef()->getWieldMesh(def.name, client);
+               has_mesh = imesh && imesh->mesh;
+       }
+       if (has_mesh) {
                scene::IMesh *mesh = imesh->mesh;
                driver->clearBuffers(video::ECBF_DEPTH);
                s32 delta = 0;
@@ -1021,9 +1038,6 @@ void drawItemStack(
                core::rect<s32> oldViewPort = driver->getViewPort();
                core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
                core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
-               core::rect<s32> viewrect = rect;
-               if (clip)
-                       viewrect.clipAgainst(*clip);
 
                core::matrix4 ProjMatrix;
                ProjMatrix.buildProjectionMatrixOrthoLH(2.0f, 2.0f, -1.0f, 100.0f);
@@ -1097,10 +1111,17 @@ void drawItemStack(
                draw_overlay = def.type == ITEM_NODE && def.inventory_image.empty();
        } else { // Otherwise just draw as 2D
                video::ITexture *texture = client->idef()->getInventoryTexture(def.name, client);
-               if (!texture)
-                       return;
-               video::SColor color =
-                       client->idef()->getItemstackColor(item, client);
+               video::SColor color;
+               if (texture) {
+                       color = client->idef()->getItemstackColor(item, client);
+               } else {
+                       color = video::SColor(255, 255, 255, 255);
+                       ITextureSource *tsrc = client->getTextureSource();
+                       texture = tsrc->getTexture("no_texture.png");
+                       if (!texture)
+                               return;
+               }
+
                const video::SColor colors[] = { color, color, color, color };
 
                draw2DImageFilterScaled(driver, texture, rect,
@@ -1160,24 +1181,68 @@ void drawItemStack(
                driver->draw2DRectangle(color, progressrect2, clip);
        }
 
-       if (font != NULL && item.count >= 2) {
+       const std::string &count_text = item.metadata.getString("count_meta");
+       if (font != nullptr && (item.count >= 2 || !count_text.empty())) {
                // Get the item count as a string
-               std::string text = itos(item.count);
-               v2u32 dim = font->getDimension(utf8_to_wide(text).c_str());
+               std::string text = count_text.empty() ? itos(item.count) : count_text;
+               v2u32 dim = font->getDimension(utf8_to_wide(unescape_enriched(text)).c_str());
                v2s32 sdim(dim.X, dim.Y);
 
                core::rect<s32> rect2(
-                       /*rect.UpperLeftCorner,
-                       core::dimension2d<u32>(rect.getWidth(), 15)*/
                        rect.LowerRightCorner - sdim,
-                       sdim
+                       rect.LowerRightCorner
                );
 
-               video::SColor bgcolor(128, 0, 0, 0);
-               driver->draw2DRectangle(bgcolor, rect2, clip);
+               // get the count alignment
+               s32 count_alignment = stoi(item.metadata.getString("count_alignment"));
+               if (count_alignment != 0) {
+                       s32 a_x = count_alignment & 3;
+                       s32 a_y = (count_alignment >> 2) & 3;
+
+                       s32 x1, x2, y1, y2;
+                       switch (a_x) {
+                       case 1: // left
+                               x1 = rect.UpperLeftCorner.X;
+                               x2 = x1 + sdim.X;
+                               break;
+                       case 2: // middle
+                               x1 = (rect.UpperLeftCorner.X + rect.LowerRightCorner.X - sdim.X) / 2;
+                               x2 = x1 + sdim.X;
+                               break;
+                       case 3: // right
+                               x2 = rect.LowerRightCorner.X;
+                               x1 = x2 - sdim.X;
+                               break;
+                       default: // 0 = default
+                               x1 = rect2.UpperLeftCorner.X;
+                               x2 = rect2.LowerRightCorner.X;
+                               break;
+                       }
+
+                       switch (a_y) {
+                       case 1: // up
+                               y1 = rect.UpperLeftCorner.Y;
+                               y2 = y1 + sdim.Y;
+                               break;
+                       case 2: // middle
+                               y1 = (rect.UpperLeftCorner.Y + rect.LowerRightCorner.Y - sdim.Y) / 2;
+                               y2 = y1 + sdim.Y;
+                               break;
+                       case 3: // down
+                               y2 = rect.LowerRightCorner.Y;
+                               y1 = y2 - sdim.Y;
+                               break;
+                       default: // 0 = default
+                               y1 = rect2.UpperLeftCorner.Y;
+                               y2 = rect2.LowerRightCorner.Y;
+                               break;
+                       }
+
+                       rect2 = core::rect<s32>(x1, y1, x2, y2);
+               }
 
                video::SColor color(255, 255, 255, 255);
-               font->draw(text.c_str(), rect2, color, false, false, clip);
+               font->draw(utf8_to_wide(text).c_str(), rect2, color, false, false, &viewrect);
        }
 }
 
index 97ad094e54453d1dc26a85e9b2295ba7a0269647..c9d1504ad6bb80168129cabac30a2115156f4a9f 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <cmath>
 #include <cassert>
 #include <vector>
+#include <algorithm>
 
 // Simple 2D bitmap class with just the functionality needed here
 class Bitmap {
@@ -123,7 +124,7 @@ void imageCleanTransparent(video::IImage *src, u32 threshold)
                        // Ignore pixels we haven't processed
                        if (!bitmap.get(sx, sy))
                                continue;
-       
+
                        // Add RGB values weighted by alpha IF the pixel is opaque, otherwise
                        // use full weight since we want to propagate colors.
                        video::SColor d = src->getPixel(sx, sy);
index 951ec88840b414432956c7467a25a2b8d049fe06..47a61d4b85ba86f6b5f454295170ab2ccfcdae6b 100644 (file)
@@ -153,8 +153,14 @@ class MyEventReceiver : public IEventReceiver
        // in the subsequent iteration of Game::processPlayerInteraction
        bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; }
 
-       void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); }
-       void dontListenForKeys() { keysListenedFor.clear(); }
+       void listenForKey(const KeyPress &keyCode)
+       {
+               keysListenedFor.set(keyCode);
+       }
+       void dontListenForKeys()
+       {
+               keysListenedFor.clear();
+       }
 
        s32 getMouseWheel()
        {
@@ -190,14 +196,14 @@ class MyEventReceiver : public IEventReceiver
 #endif
        }
 
-       s32 mouse_wheel = 0;
-
        JoystickController *joystick = nullptr;
 
 #ifdef HAVE_TOUCHSCREENGUI
        TouchScreenGUI *m_touchscreengui;
 #endif
 
+       s32 mouse_wheel = 0;
+
        // The current state of keys
        KeyList keyIsDown;
 
@@ -274,6 +280,12 @@ class RealInputHandler : public InputHandler
        {
                m_receiver->joystick = &joystick;
        }
+
+       virtual ~RealInputHandler()
+       {
+               m_receiver->joystick = nullptr;
+       }
+
        virtual bool isKeyDown(GameKeyType k)
        {
                return m_receiver->IsKeyDown(keycache.key[k]) || joystick.isKeyDown(k);
@@ -299,6 +311,7 @@ class RealInputHandler : public InputHandler
        {
                return m_receiver->WasKeyReleased(keycache.key[k]) || joystick.wasKeyReleased(k);
        }
+
        virtual float getMovementSpeed()
        {
                bool f = m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD]),
@@ -318,6 +331,7 @@ class RealInputHandler : public InputHandler
                }
                return joystick.getMovementSpeed();
        }
+
        virtual float getMovementDirection()
        {
                float x = 0, z = 0;
@@ -337,10 +351,12 @@ class RealInputHandler : public InputHandler
                else
                        return joystick.getMovementDirection();
        }
+
        virtual bool cancelPressed()
        {
                return wasKeyDown(KeyType::ESC) || m_receiver->WasKeyDown(CancelKey);
        }
+
        virtual void clearWasKeyPressed()
        {
                m_receiver->clearWasKeyPressed();
@@ -349,17 +365,21 @@ class RealInputHandler : public InputHandler
        {
                m_receiver->clearWasKeyReleased();
        }
+
        virtual void listenForKey(const KeyPress &keyCode)
        {
                m_receiver->listenForKey(keyCode);
        }
-       virtual void dontListenForKeys() { m_receiver->dontListenForKeys(); }
+       virtual void dontListenForKeys()
+       {
+               m_receiver->dontListenForKeys();
+       }
+
        virtual v2s32 getMousePos()
        {
-               if (RenderingEngine::get_raw_device()->getCursorControl()) {
-                       return RenderingEngine::get_raw_device()
-                                       ->getCursorControl()
-                                       ->getPosition();
+               auto control = RenderingEngine::get_raw_device()->getCursorControl();
+               if (control) {
+                       return control->getPosition();
                }
 
                return m_mousepos;
@@ -367,16 +387,18 @@ class RealInputHandler : public InputHandler
 
        virtual void setMousePos(s32 x, s32 y)
        {
-               if (RenderingEngine::get_raw_device()->getCursorControl()) {
-                       RenderingEngine::get_raw_device()
-                                       ->getCursorControl()
-                                       ->setPosition(x, y);
+               auto control = RenderingEngine::get_raw_device()->getCursorControl();
+               if (control) {
+                       control->setPosition(x, y);
                } else {
                        m_mousepos = v2s32(x, y);
                }
        }
 
-       virtual s32 getMouseWheel() { return m_receiver->getMouseWheel(); }
+       virtual s32 getMouseWheel()
+       {
+               return m_receiver->getMouseWheel();
+       }
 
        void clear()
        {
@@ -384,7 +406,7 @@ class RealInputHandler : public InputHandler
                m_receiver->clearInput();
        }
 
-       private:
+private:
        MyEventReceiver *m_receiver = nullptr;
        v2s32 m_mousepos;
 };
index 630565d8db41c42444c5db2ebb4219dbab355d13..aae73c62d205c783c5e4d038709e331bf2eefdb0 100644 (file)
@@ -154,6 +154,54 @@ JoystickLayout create_xbox_layout()
        return jlo;
 }
 
+JoystickLayout create_dragonrise_gamecube_layout()
+{
+       JoystickLayout jlo;
+
+       jlo.axes_deadzone = 7000;
+
+       const JoystickAxisLayout axes[JA_COUNT] = {
+               // Control Stick
+               {0, 1}, // JA_SIDEWARD_MOVE
+               {1, 1}, // JA_FORWARD_MOVE
+
+               // C-Stick
+               {3, 1}, // JA_FRUSTUM_HORIZONTAL
+               {4, 1}, // JA_FRUSTUM_VERTICAL
+       };
+       memcpy(jlo.axes, axes, sizeof(jlo.axes));
+
+       // The center button
+       JLO_B_PB(KeyType::ESC, 1 << 9, 1 << 9); // Start/Pause Button
+
+       // Front right buttons
+       JLO_B_PB(KeyType::JUMP,  1 << 2, 1 << 2); // A Button
+       JLO_B_PB(KeyType::SNEAK, 1 << 3, 1 << 3); // B Button
+       JLO_B_PB(KeyType::DROP,  1 << 0, 1 << 0); // Y Button
+       JLO_B_PB(KeyType::AUX1,  1 << 1, 1 << 1); // X Button
+
+       // Triggers
+       JLO_B_PB(KeyType::DIG,       1 << 4, 1 << 4); // L Trigger
+       JLO_B_PB(KeyType::PLACE,     1 << 5, 1 << 5); // R Trigger
+       JLO_B_PB(KeyType::INVENTORY, 1 << 6, 1 << 6); // Z Button
+
+       // D-Pad
+       JLO_A_PB(KeyType::HOTBAR_PREV, 5,  1, jlo.axes_deadzone); // left
+       JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, jlo.axes_deadzone); // right
+       // Axis are hard to actuate independantly, best to leave up and down unused.
+       //JLO_A_PB(0, 6,  1, jlo.axes_deadzone); // up
+       //JLO_A_PB(0, 6, -1, jlo.axes_deadzone); // down
+
+       // Movements tied to Control Stick, important for vessels
+       JLO_A_PB(KeyType::LEFT,     0,  1, jlo.axes_deadzone);
+       JLO_A_PB(KeyType::RIGHT,    0, -1, jlo.axes_deadzone);
+       JLO_A_PB(KeyType::FORWARD,  1,  1, jlo.axes_deadzone);
+       JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone);
+
+       return jlo;
+}
+
+
 JoystickController::JoystickController() :
                doubling_dtime(g_settings->getFloat("repeat_joystick_button_time"))
 {
@@ -188,6 +236,8 @@ void JoystickController::setLayoutFromControllerName(const std::string &name)
 {
        if (lowercase(name).find("xbox") != std::string::npos) {
                m_layout = create_xbox_layout();
+       } else if (lowercase(name).find("dragonrise_gamecube") != std::string::npos) {
+               m_layout = create_dragonrise_gamecube_layout();
        } else {
                m_layout = create_default_layout();
        }
index ca61f3a11e81beff96b654c66a8e307ae6994e66..c4d9b98457d6c10574b5e7aec07e964c2db52d60 100644 (file)
@@ -232,8 +232,9 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                pp = floatToInt(position + v3f(0.0f, BS * 0.1f, 0.0f), BS);
                node = map->getNode(pp, &is_valid_position);
                if (is_valid_position) {
-                       in_liquid = nodemgr->get(node.getContent()).isLiquid();
-                       liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity;
+                       const ContentFeatures &cf = nodemgr->get(node.getContent());
+                       in_liquid = cf.liquid_move_physics;
+                       move_resistance = cf.move_resistance;
                } else {
                        in_liquid = false;
                }
@@ -243,8 +244,9 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
                pp = floatToInt(position + v3f(0.0f, BS * 0.5f, 0.0f), BS);
                node = map->getNode(pp, &is_valid_position);
                if (is_valid_position) {
-                       in_liquid = nodemgr->get(node.getContent()).isLiquid();
-                       liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity;
+                       const ContentFeatures &cf = nodemgr->get(node.getContent());
+                       in_liquid = cf.liquid_move_physics;
+                       move_resistance = cf.move_resistance;
                } else {
                        in_liquid = false;
                }
@@ -257,7 +259,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
        pp = floatToInt(position + v3f(0.0f), BS);
        node = map->getNode(pp, &is_valid_position);
        if (is_valid_position) {
-               in_liquid_stable = nodemgr->get(node.getContent()).isLiquid();
+               in_liquid_stable = nodemgr->get(node.getContent()).liquid_move_physics;
        } else {
                in_liquid_stable = false;
        }
@@ -694,19 +696,21 @@ v3s16 LocalPlayer::getStandingNodePos()
 
 v3s16 LocalPlayer::getFootstepNodePos()
 {
+       v3f feet_pos = getPosition() + v3f(0.0f, m_collisionbox.MinEdge.Y, 0.0f);
+
        // Emit swimming sound if the player is in liquid
        if (in_liquid_stable)
-               return floatToInt(getPosition(), BS);
+               return floatToInt(feet_pos, BS);
 
        // BS * 0.05 below the player's feet ensures a 1/16th height
        // nodebox is detected instead of the node below it.
        if (touching_ground)
-               return floatToInt(getPosition() - v3f(0.0f, BS * 0.05f, 0.0f), BS);
+               return floatToInt(feet_pos - v3f(0.0f, BS * 0.05f, 0.0f), BS);
 
        // A larger distance below is necessary for a footstep sound
        // when landing after a jump or fall. BS * 0.5 ensures water
        // sounds when swimming in 1 node deep water.
-       return floatToInt(getPosition() - v3f(0.0f, BS * 0.5f, 0.0f), BS);
+       return floatToInt(feet_pos - v3f(0.0f, BS * 0.5f, 0.0f), BS);
 }
 
 v3s16 LocalPlayer::getLightPosition() const
@@ -846,8 +850,9 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
                pp = floatToInt(position + v3f(0.0f, BS * 0.1f, 0.0f), BS);
                node = map->getNode(pp, &is_valid_position);
                if (is_valid_position) {
-                       in_liquid = nodemgr->get(node.getContent()).isLiquid();
-                       liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity;
+                       const ContentFeatures &cf = nodemgr->get(node.getContent());
+                       in_liquid = cf.liquid_move_physics;
+                       move_resistance = cf.move_resistance;
                } else {
                        in_liquid = false;
                }
@@ -856,8 +861,9 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
                pp = floatToInt(position + v3f(0.0f, BS * 0.5f, 0.0f), BS);
                node = map->getNode(pp, &is_valid_position);
                if (is_valid_position) {
-                       in_liquid = nodemgr->get(node.getContent()).isLiquid();
-                       liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity;
+                       const ContentFeatures &cf = nodemgr->get(node.getContent());
+                       in_liquid = cf.liquid_move_physics;
+                       move_resistance = cf.move_resistance;
                } else {
                        in_liquid = false;
                }
@@ -869,7 +875,7 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
        pp = floatToInt(position + v3f(0.0f), BS);
        node = map->getNode(pp, &is_valid_position);
        if (is_valid_position)
-               in_liquid_stable = nodemgr->get(node.getContent()).isLiquid();
+               in_liquid_stable = nodemgr->get(node.getContent()).liquid_move_physics;
        else
                in_liquid_stable = false;
 
@@ -1138,10 +1144,8 @@ void LocalPlayer::handleAutojump(f32 dtime, Environment *env,
        if (m_autojump)
                return;
 
-       bool control_forward = keyPressed & (1 << 0);
-
        bool could_autojump =
-               m_can_jump && !control.jump && !control.sneak && control_forward;
+               m_can_jump && !control.jump && !control.sneak && control.isMoving();
 
        if (!could_autojump)
                return;
index eaac216d3e7187db7dd4424b949c02cbff89f19d..ebc67c4f8c7849844375ca3bacbb60cb3fcb146a 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "environment.h"
 #include "constants.h"
 #include "settings.h"
+#include "lighting.h"
 #include <list>
 
 class Client;
@@ -56,8 +57,8 @@ class LocalPlayer : public Player
        bool in_liquid = false;
        // This is more stable and defines the maximum speed of the player
        bool in_liquid_stable = false;
-       // Gets the viscosity of water to calculate friction
-       u8 liquid_viscosity = 0;
+       // Slows down the player when moving through
+       u8 move_resistance = 0;
        bool is_climbing = false;
        bool swimming_vertical = false;
        bool swimming_pitch = false;
@@ -87,7 +88,7 @@ class LocalPlayer : public Player
        v3f last_speed;
        float last_pitch = 0.0f;
        float last_yaw = 0.0f;
-       unsigned int last_keyPressed = 0;
+       u32 last_keyPressed = 0;
        u8 last_camera_fov = 0;
        u8 last_wanted_range = 0;
 
@@ -187,6 +188,8 @@ class LocalPlayer : public Player
                added_velocity += vel;
        }
 
+       inline Lighting& getLighting() { return m_lighting; }
+
        void tryReattach(int id);
 
        bool isWaitingForReattach() const;
@@ -247,4 +250,5 @@ class LocalPlayer : public Player
 
        GenericCAO *m_cao = nullptr;
        Client *m_client;
+       Lighting m_lighting;
 };
index 52729632a6c143f0ad93b14e99c6f21f434f8e26..f0d43ec7e2f12dac890382faa75ba1d2a61ac035 100644 (file)
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client/meshgen/collector.h"
 #include "client/renderingengine.h"
 #include <array>
+#include <algorithm>
 
 /*
        MeshMakeData
@@ -1045,6 +1046,173 @@ static void applyTileColor(PreMeshBuffer &pmb)
        }
 }
 
+/*
+       MapBlockBspTree
+*/
+
+void MapBlockBspTree::buildTree(const std::vector<MeshTriangle> *triangles)
+{
+       this->triangles = triangles;
+
+       nodes.clear();
+
+       // assert that triangle index can fit into s32
+       assert(triangles->size() <= 0x7FFFFFFFL);
+       std::vector<s32> indexes;
+       indexes.reserve(triangles->size());
+       for (u32 i = 0; i < triangles->size(); i++)
+               indexes.push_back(i);
+
+       root = buildTree(v3f(1, 0, 0), v3f(85, 85, 85), 40, indexes, 0);
+}
+
+/**
+ * @brief Find a candidate plane to split a set of triangles in two
+ * 
+ * The candidate plane is represented by one of the triangles from the set.
+ * 
+ * @param list Vector of indexes of the triangles in the set
+ * @param triangles Vector of all triangles in the BSP tree
+ * @return Address of the triangle that represents the proposed split plane
+ */
+static const MeshTriangle *findSplitCandidate(const std::vector<s32> &list, const std::vector<MeshTriangle> &triangles)
+{
+       // find the center of the cluster.
+       v3f center(0, 0, 0);
+       size_t n = list.size();
+       for (s32 i : list) {
+               center += triangles[i].centroid / n;
+       }
+
+       // find the triangle with the largest area and closest to the center
+       const MeshTriangle *candidate_triangle = &triangles[list[0]];
+       const MeshTriangle *ith_triangle;
+       for (s32 i : list) {
+               ith_triangle = &triangles[i];
+               if (ith_triangle->areaSQ > candidate_triangle->areaSQ ||
+                               (ith_triangle->areaSQ == candidate_triangle->areaSQ &&
+                               ith_triangle->centroid.getDistanceFromSQ(center) < candidate_triangle->centroid.getDistanceFromSQ(center))) {
+                       candidate_triangle = ith_triangle;
+               }
+       }
+       return candidate_triangle;
+}
+
+s32 MapBlockBspTree::buildTree(v3f normal, v3f origin, float delta, const std::vector<s32> &list, u32 depth)
+{
+       // if the list is empty, don't bother
+       if (list.empty())
+               return -1;
+
+       // if there is only one triangle, or the delta is insanely small, this is a leaf node
+       if (list.size() == 1 || delta < 0.01) {
+               nodes.emplace_back(normal, origin, list, -1, -1);
+               return nodes.size() - 1;
+       }
+
+       std::vector<s32> front_list;
+       std::vector<s32> back_list;
+       std::vector<s32> node_list;
+
+       // split the list
+       for (s32 i : list) {
+               const MeshTriangle &triangle = (*triangles)[i];
+               float factor = normal.dotProduct(triangle.centroid - origin);
+               if (factor == 0)
+                       node_list.push_back(i);
+               else if (factor > 0)
+                       front_list.push_back(i);
+               else
+                       back_list.push_back(i);
+       }
+
+       // define the new split-plane
+       v3f candidate_normal(normal.Z, normal.X, normal.Y);
+       float candidate_delta = delta;
+       if (depth % 3 == 2)
+               candidate_delta /= 2;
+
+       s32 front_index = -1;
+       s32 back_index = -1;
+
+       if (!front_list.empty()) {
+               v3f next_normal = candidate_normal;
+               v3f next_origin = origin + delta * normal;
+               float next_delta = candidate_delta;
+               if (next_delta < 10) {
+                       const MeshTriangle *candidate = findSplitCandidate(front_list, *triangles);
+                       next_normal = candidate->getNormal();
+                       next_origin = candidate->centroid;
+               }
+               front_index = buildTree(next_normal, next_origin, next_delta, front_list, depth + 1);
+
+               // if there are no other triangles, don't create a new node
+               if (back_list.empty() && node_list.empty())
+                       return front_index;
+       }
+
+       if (!back_list.empty()) {
+               v3f next_normal = candidate_normal;
+               v3f next_origin = origin - delta * normal;
+               float next_delta = candidate_delta;
+               if (next_delta < 10) {
+                       const MeshTriangle *candidate = findSplitCandidate(back_list, *triangles);
+                       next_normal = candidate->getNormal();
+                       next_origin = candidate->centroid;
+               }
+
+               back_index = buildTree(next_normal, next_origin, next_delta, back_list, depth + 1);
+
+               // if there are no other triangles, don't create a new node
+               if (front_list.empty() && node_list.empty())
+                       return back_index;
+       }
+
+       nodes.emplace_back(normal, origin, node_list, front_index, back_index);
+
+       return nodes.size() - 1;
+}
+
+void MapBlockBspTree::traverse(s32 node, v3f viewpoint, std::vector<s32> &output) const
+{
+       if (node < 0) return; // recursion break;
+
+       const TreeNode &n = nodes[node];
+       float factor = n.normal.dotProduct(viewpoint - n.origin);
+
+       if (factor > 0)
+               traverse(n.back_ref, viewpoint, output);
+       else
+               traverse(n.front_ref, viewpoint, output);
+
+       if (factor != 0)
+               for (s32 i : n.triangle_refs)
+                       output.push_back(i);
+
+       if (factor > 0)
+               traverse(n.front_ref, viewpoint, output);
+       else
+               traverse(n.back_ref, viewpoint, output);
+}
+
+
+
+/*
+       PartialMeshBuffer
+*/
+
+void PartialMeshBuffer::beforeDraw() const
+{
+       // Patch the indexes in the mesh buffer before draw
+
+       m_buffer->Indices.clear();
+       if (!m_vertex_indexes.empty()) {
+               for (auto index : m_vertex_indexes)
+                       m_buffer->Indices.push_back(index);
+       }
+       m_buffer->setDirty(scene::EBT_INDEX);
+}
+
 /*
        MapBlockMesh
 */
@@ -1152,6 +1320,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
                Convert MeshCollector to SMesh
        */
 
+       const bool desync_animations = g_settings->getBool(
+               "desynchronize_mapblock_texture_animation");
+
        for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
                for(u32 i = 0; i < collector.prebuffers[layer].size(); i++)
                {
@@ -1181,18 +1352,18 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
                        // - Texture animation
                        if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
                                // Add to MapBlockMesh in order to animate these tiles
-                               m_animation_tiles[std::pair<u8, u32>(layer, i)] = p.layer;
-                               m_animation_frames[std::pair<u8, u32>(layer, i)] = 0;
-                               if (g_settings->getBool(
-                                               "desynchronize_mapblock_texture_animation")) {
+                               auto &info = m_animation_info[{layer, i}];
+                               info.tile = p.layer;
+                               info.frame = 0;
+                               if (desync_animations) {
                                        // Get starting position from noise
-                                       m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] =
+                                       info.frame_offset =
                                                        100000 * (2.0 + noise3d(
                                                        data->m_blockpos.X, data->m_blockpos.Y,
                                                        data->m_blockpos.Z, 0));
                                } else {
                                        // Play all synchronized
-                                       m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] = 0;
+                                       info.frame_offset = 0;
                                }
                                // Replace tile texture with the first animation frame
                                p.layer.texture = (*p.layer.frames)[0].texture;
@@ -1203,19 +1374,23 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
                                // Dummy sunlight to handle non-sunlit areas
                                video::SColorf sunlight;
                                get_sunlight_color(&sunlight, 0);
-                               u32 vertex_count = p.vertices.size();
+
+                               std::map<u32, video::SColor> colors;
+                               const u32 vertex_count = p.vertices.size();
                                for (u32 j = 0; j < vertex_count; j++) {
                                        video::SColor *vc = &p.vertices[j].Color;
                                        video::SColor copy = *vc;
                                        if (vc->getAlpha() == 0) // No sunlight - no need to animate
                                                final_color_blend(vc, copy, sunlight); // Finalize color
                                        else // Record color to animate
-                                               m_daynight_diffs[std::pair<u8, u32>(layer, i)][j] = copy;
+                                               colors[j] = copy;
 
                                        // The sunlight ratio has been stored,
                                        // delete alpha (for the final rendering).
                                        vc->setAlpha(255);
                                }
+                               if (!colors.empty())
+                                       m_daynight_diffs[{layer, i}] = std::move(colors);
                        }
 
                        // Create material
@@ -1241,8 +1416,31 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
 
                        scene::SMeshBuffer *buf = new scene::SMeshBuffer();
                        buf->Material = material;
-                       buf->append(&p.vertices[0], p.vertices.size(),
-                               &p.indices[0], p.indices.size());
+                       switch (p.layer.material_type) {
+                       // list of transparent materials taken from tile.h
+                       case TILE_MATERIAL_ALPHA:
+                       case TILE_MATERIAL_LIQUID_TRANSPARENT:
+                       case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
+                               {
+                                       buf->append(&p.vertices[0], p.vertices.size(),
+                                               &p.indices[0], 0);
+
+                                       MeshTriangle t;
+                                       t.buffer = buf;
+                                       for (u32 i = 0; i < p.indices.size(); i += 3) {
+                                               t.p1 = p.indices[i];
+                                               t.p2 = p.indices[i + 1];
+                                               t.p3 = p.indices[i + 2];
+                                               t.updateAttributes();
+                                               m_transparent_triangles.push_back(t);
+                                       }
+                               }
+                               break;
+                       default:
+                               buf->append(&p.vertices[0], p.vertices.size(),
+                                       &p.indices[0], p.indices.size());
+                               break;
+                       }
                        mesh->addMeshBuffer(buf);
                        buf->drop();
                }
@@ -1255,23 +1453,26 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
        }
 
        //std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
+       m_bsp_tree.buildTree(&m_transparent_triangles);
 
        // Check if animation is required for this mesh
        m_has_animation =
                !m_crack_materials.empty() ||
                !m_daynight_diffs.empty() ||
-               !m_animation_tiles.empty();
+               !m_animation_info.empty();
 }
 
 MapBlockMesh::~MapBlockMesh()
 {
        for (scene::IMesh *m : m_mesh) {
+#if IRRLICHT_VERSION_MT_REVISION < 5
                if (m_enable_vbo) {
                        for (u32 i = 0; i < m->getMeshBufferCount(); i++) {
                                scene::IMeshBuffer *buf = m->getMeshBuffer(i);
                                RenderingEngine::get_video_driver()->removeHardwareBuffer(buf);
                        }
                }
+#endif
                m->drop();
        }
        delete m_minimap_mapblock;
@@ -1292,25 +1493,22 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
                for (auto &crack_material : m_crack_materials) {
                        scene::IMeshBuffer *buf = m_mesh[crack_material.first.first]->
                                getMeshBuffer(crack_material.first.second);
-                       std::string basename = crack_material.second;
 
                        // Create new texture name from original
-                       std::ostringstream os;
-                       os << basename << crack;
+                       std::string s = crack_material.second + itos(crack);
                        u32 new_texture_id = 0;
                        video::ITexture *new_texture =
-                                       m_tsrc->getTextureForMesh(os.str(), &new_texture_id);
+                                       m_tsrc->getTextureForMesh(s, &new_texture_id);
                        buf->getMaterial().setTexture(0, new_texture);
 
-                       // If the current material is also animated,
-                       // update animation info
-                       auto anim_iter = m_animation_tiles.find(crack_material.first);
-                       if (anim_iter != m_animation_tiles.end()) {
-                               TileLayer &tile = anim_iter->second;
+                       // If the current material is also animated, update animation info
+                       auto anim_it = m_animation_info.find(crack_material.first);
+                       if (anim_it != m_animation_info.end()) {
+                               TileLayer &tile = anim_it->second.tile;
                                tile.texture = new_texture;
                                tile.texture_id = new_texture_id;
                                // force animation update
-                               m_animation_frames[crack_material.first] = -1;
+                               anim_it->second.frame = -1;
                        }
                }
 
@@ -1318,28 +1516,25 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
        }
 
        // Texture animation
-       for (auto &animation_tile : m_animation_tiles) {
-               const TileLayer &tile = animation_tile.second;
+       for (auto &it : m_animation_info) {
+               const TileLayer &tile = it.second.tile;
                // Figure out current frame
-               int frameoffset = m_animation_frame_offsets[animation_tile.first];
-               int frame = (int)(time * 1000 / tile.animation_frame_length_ms
-                               + frameoffset) % tile.animation_frame_count;
+               int frameno = (int)(time * 1000 / tile.animation_frame_length_ms
+                               + it.second.frame_offset) % tile.animation_frame_count;
                // If frame doesn't change, skip
-               if (frame == m_animation_frames[animation_tile.first])
+               if (frameno == it.second.frame)
                        continue;
 
-               m_animation_frames[animation_tile.first] = frame;
+               it.second.frame = frameno;
 
-               scene::IMeshBuffer *buf = m_mesh[animation_tile.first.first]->
-                       getMeshBuffer(animation_tile.first.second);
+               scene::IMeshBuffer *buf = m_mesh[it.first.first]->getMeshBuffer(it.first.second);
 
-               const FrameSpec &animation_frame = (*tile.frames)[frame];
-               buf->getMaterial().setTexture(0, animation_frame.texture);
+               const FrameSpec &frame = (*tile.frames)[frameno];
+               buf->getMaterial().setTexture(0, frame.texture);
                if (m_enable_shaders) {
-                       if (animation_frame.normal_texture)
-                               buf->getMaterial().setTexture(1,
-                                       animation_frame.normal_texture);
-                       buf->getMaterial().setTexture(2, animation_frame.flags_texture);
+                       if (frame.normal_texture)
+                               buf->getMaterial().setTexture(1, frame.normal_texture);
+                       buf->getMaterial().setTexture(2, frame.flags_texture);
                }
        }
 
@@ -1366,6 +1561,67 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
        return true;
 }
 
+void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
+{
+       // nothing to do if the entire block is opaque
+       if (m_transparent_triangles.empty())
+               return;
+
+       v3f block_posf = intToFloat(block_pos * MAP_BLOCKSIZE, BS);
+       v3f rel_camera_pos = camera_pos - block_posf;
+
+       std::vector<s32> triangle_refs;
+       m_bsp_tree.traverse(rel_camera_pos, triangle_refs);
+
+       // arrange index sequences into partial buffers
+       m_transparent_buffers.clear();
+
+       scene::SMeshBuffer *current_buffer = nullptr;
+       std::vector<u16> current_strain;
+       for (auto i : triangle_refs) {
+               const auto &t = m_transparent_triangles[i];
+               if (current_buffer != t.buffer) {
+                       if (current_buffer) {
+                               m_transparent_buffers.emplace_back(current_buffer, current_strain);
+                               current_strain.clear();
+                       }
+                       current_buffer = t.buffer;
+               }
+               current_strain.push_back(t.p1);
+               current_strain.push_back(t.p2);
+               current_strain.push_back(t.p3);
+       }
+
+       if (!current_strain.empty())
+               m_transparent_buffers.emplace_back(current_buffer, current_strain);
+}
+
+void MapBlockMesh::consolidateTransparentBuffers()
+{
+       m_transparent_buffers.clear();
+
+       scene::SMeshBuffer *current_buffer = nullptr;
+       std::vector<u16> current_strain;
+
+       // use the fact that m_transparent_triangles is already arranged by buffer
+       for (const auto &t : m_transparent_triangles) {
+               if (current_buffer != t.buffer) {
+                       if (current_buffer != nullptr) {
+                               this->m_transparent_buffers.emplace_back(current_buffer, current_strain);
+                               current_strain.clear();
+                       }
+                       current_buffer = t.buffer;
+               }
+               current_strain.push_back(t.p1);
+               current_strain.push_back(t.p2);
+               current_strain.push_back(t.p3);
+       }
+
+       if (!current_strain.empty()) {
+               this->m_transparent_buffers.emplace_back(current_buffer, current_strain);
+       }
+}
+
 video::SColor encode_light(u16 light, u8 emissive_light)
 {
        // Get components
index 80075fce242ed07c52fdf525249f96b1ff8aa70f..5e2d70b755a204622131c7f389249a42ecb80a0d 100644 (file)
@@ -71,6 +71,91 @@ struct MeshMakeData
        void setSmoothLighting(bool smooth_lighting);
 };
 
+// represents a triangle as indexes into the vertex buffer in SMeshBuffer
+class MeshTriangle
+{
+public:
+       scene::SMeshBuffer *buffer;
+       u16 p1, p2, p3;
+       v3f centroid;
+       float areaSQ;
+
+       void updateAttributes()
+       {
+               v3f v1 = buffer->getPosition(p1);
+               v3f v2 = buffer->getPosition(p2);
+               v3f v3 = buffer->getPosition(p3);
+
+               centroid = (v1 + v2 + v3) / 3;
+               areaSQ = (v2-v1).crossProduct(v3-v1).getLengthSQ() / 4;
+       }
+
+       v3f getNormal() const {
+               v3f v1 = buffer->getPosition(p1);
+               v3f v2 = buffer->getPosition(p2);
+               v3f v3 = buffer->getPosition(p3);
+
+               return (v2-v1).crossProduct(v3-v1);
+       }
+};
+
+/**
+ * Implements a binary space partitioning tree 
+ * See also: https://en.wikipedia.org/wiki/Binary_space_partitioning
+ */
+class MapBlockBspTree
+{
+public:
+       MapBlockBspTree() {}
+
+       void buildTree(const std::vector<MeshTriangle> *triangles);
+
+       void traverse(v3f viewpoint, std::vector<s32> &output) const
+       {
+               traverse(root, viewpoint, output);
+       }
+
+private:
+       // Tree node definition;
+       struct TreeNode
+       {
+               v3f normal;
+               v3f origin;
+               std::vector<s32> triangle_refs;
+               s32 front_ref;
+               s32 back_ref;
+
+               TreeNode() = default;
+               TreeNode(v3f normal, v3f origin, const std::vector<s32> &triangle_refs, s32 front_ref, s32 back_ref) :
+                               normal(normal), origin(origin), triangle_refs(triangle_refs), front_ref(front_ref), back_ref(back_ref)
+               {}
+       };
+
+
+       s32 buildTree(v3f normal, v3f origin, float delta, const std::vector<s32> &list, u32 depth);
+       void traverse(s32 node, v3f viewpoint, std::vector<s32> &output) const;
+
+       const std::vector<MeshTriangle> *triangles = nullptr; // this reference is managed externally
+       std::vector<TreeNode> nodes; // list of nodes
+       s32 root = -1; // index of the root node
+};
+
+class PartialMeshBuffer
+{
+public:
+       PartialMeshBuffer(scene::SMeshBuffer *buffer, const std::vector<u16> &vertex_indexes) :
+                       m_buffer(buffer), m_vertex_indexes(vertex_indexes)
+       {}
+
+       scene::IMeshBuffer *getBuffer() const { return m_buffer; }
+       const std::vector<u16> &getVertexIndexes() const { return m_vertex_indexes; }
+
+       void beforeDraw() const;
+private:
+       scene::SMeshBuffer *m_buffer;
+       std::vector<u16> m_vertex_indexes;
+};
+
 /*
        Holds a mesh for a mapblock.
 
@@ -125,9 +210,25 @@ class MapBlockMesh
                        m_animation_force_timer--;
        }
 
+       /// update transparent buffers to render towards the camera
+       void updateTransparentBuffers(v3f camera_pos, v3s16 block_pos);
+       void consolidateTransparentBuffers();
+
+       /// get the list of transparent buffers
+       const std::vector<PartialMeshBuffer> &getTransparentBuffers() const
+       {
+               return this->m_transparent_buffers;
+       }
+
        std::set<v3s16> esp_nodes;
 
 private:
+       struct AnimationInfo {
+               int frame; // last animation frame
+               int frame_offset;
+               TileLayer tile;
+       };
+
        scene::IMesh *m_mesh[MAX_TILE_LAYERS];
        MinimapMapblock *m_minimap_mapblock;
        ITextureSource *m_tsrc;
@@ -146,12 +247,10 @@ class MapBlockMesh
        // Maps mesh and mesh buffer (i.e. material) indices to base texture names
        std::map<std::pair<u8, u32>, std::string> m_crack_materials;
 
-       // Animation info: texture animationi
+       // Animation info: texture animation
        // Maps mesh and mesh buffer indices to TileSpecs
        // Keys are pairs of (mesh index, buffer index in the mesh)
-       std::map<std::pair<u8, u32>, TileLayer> m_animation_tiles;
-       std::map<std::pair<u8, u32>, int> m_animation_frames; // last animation frame
-       std::map<std::pair<u8, u32>, int> m_animation_frame_offsets;
+       std::map<std::pair<u8, u32>, AnimationInfo> m_animation_info;
 
        // Animation info: day/night transitions
        // Last daynight_ratio value passed to animate()
@@ -160,6 +259,13 @@ class MapBlockMesh
        // of sunlit vertices
        // Keys are pairs of (mesh index, buffer index in the mesh)
        std::map<std::pair<u8, u32>, std::map<u32, video::SColor > > m_daynight_diffs;
+
+       // list of all semitransparent triangles in the mapblock
+       std::vector<MeshTriangle> m_transparent_triangles;
+       // Binary Space Partitioning tree for the block
+       MapBlockBspTree m_bsp_tree;
+       // Ordered list of references to parts of transparent buffers to draw
+       std::vector<PartialMeshBuffer> m_transparent_buffers;
 };
 
 /*!
index e4313921895505f64594fe403306641f16db3bc5..bec72fb5e79b13f27a89b3043fa12aa644511372 100644 (file)
@@ -331,6 +331,9 @@ void recalculateBoundingBox(scene::IMesh *src_mesh)
 
 bool checkMeshNormals(scene::IMesh *mesh)
 {
+       // Assume correct normals if this many first faces get it right.
+       static const u16 MAX_FACES_TO_CHECK = 9;
+
        u32 buffer_count = mesh->getMeshBufferCount();
 
        for (u32 i = 0; i < buffer_count; i++) {
@@ -344,6 +347,19 @@ bool checkMeshNormals(scene::IMesh *mesh)
 
                if (!std::isfinite(length) || length < 1e-10f)
                        return false;
+
+               const u16 count = MYMIN(MAX_FACES_TO_CHECK * 3, buffer->getIndexCount() - 3);
+               for (u16 i = 0; i < count; i += 3) {
+
+                       core::plane3df plane(buffer->getPosition(buffer->getIndices()[i]),
+                                       buffer->getPosition(buffer->getIndices()[i+1]),
+                                       buffer->getPosition(buffer->getIndices()[i+2]));
+
+                       for (u16 j = 0; j < 3; j++)
+                               if (plane.Normal.dotProduct(buffer->getNormal(buffer->getIndices()[i+j])) <= 0)
+                                       return false;
+               }
+
        }
 
        return true;
@@ -498,592 +514,3 @@ scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
        }
        return dst_mesh;
 }
-
-struct vcache
-{
-       core::array<u32> tris;
-       float score;
-       s16 cachepos;
-       u16 NumActiveTris;
-};
-
-struct tcache
-{
-       u16 ind[3];
-       float score;
-       bool drawn;
-};
-
-const u16 cachesize = 32;
-
-float FindVertexScore(vcache *v)
-{
-       const float CacheDecayPower = 1.5f;
-       const float LastTriScore = 0.75f;
-       const float ValenceBoostScale = 2.0f;
-       const float ValenceBoostPower = 0.5f;
-       const float MaxSizeVertexCache = 32.0f;
-
-       if (v->NumActiveTris == 0)
-       {
-               // No tri needs this vertex!
-               return -1.0f;
-       }
-
-       float Score = 0.0f;
-       int CachePosition = v->cachepos;
-       if (CachePosition < 0)
-       {
-               // Vertex is not in FIFO cache - no score.
-       }
-       else
-       {
-               if (CachePosition < 3)
-               {
-                       // This vertex was used in the last triangle,
-                       // so it has a fixed score.
-                       Score = LastTriScore;
-               }
-               else
-               {
-                       // Points for being high in the cache.
-                       const float Scaler = 1.0f / (MaxSizeVertexCache - 3);
-                       Score = 1.0f - (CachePosition - 3) * Scaler;
-                       Score = powf(Score, CacheDecayPower);
-               }
-       }
-
-       // Bonus points for having a low number of tris still to
-       // use the vert, so we get rid of lone verts quickly.
-       float ValenceBoost = powf(v->NumActiveTris,
-                               -ValenceBoostPower);
-       Score += ValenceBoostScale * ValenceBoost;
-
-       return Score;
-}
-
-/*
-       A specialized LRU cache for the Forsyth algorithm.
-*/
-
-class f_lru
-{
-
-public:
-       f_lru(vcache *v, tcache *t): vc(v), tc(t)
-       {
-               for (int &i : cache) {
-                       i = -1;
-               }
-       }
-
-       // Adds this vertex index and returns the highest-scoring triangle index
-       u32 add(u16 vert, bool updatetris = false)
-       {
-               bool found = false;
-
-               // Mark existing pos as empty
-               for (u16 i = 0; i < cachesize; i++)
-               {
-                       if (cache[i] == vert)
-                       {
-                               // Move everything down
-                               for (u16 j = i; j; j--)
-                               {
-                                       cache[j] = cache[j - 1];
-                               }
-
-                               found = true;
-                               break;
-                       }
-               }
-
-               if (!found)
-               {
-                       if (cache[cachesize-1] != -1)
-                               vc[cache[cachesize-1]].cachepos = -1;
-
-                       // Move everything down
-                       for (u16 i = cachesize - 1; i; i--)
-                       {
-                               cache[i] = cache[i - 1];
-                       }
-               }
-
-               cache[0] = vert;
-
-               u32 highest = 0;
-               float hiscore = 0;
-
-               if (updatetris)
-               {
-                       // Update cache positions
-                       for (u16 i = 0; i < cachesize; i++)
-                       {
-                               if (cache[i] == -1)
-                                       break;
-
-                               vc[cache[i]].cachepos = i;
-                               vc[cache[i]].score = FindVertexScore(&vc[cache[i]]);
-                       }
-
-                       // Update triangle scores
-                       for (int i : cache) {
-                               if (i == -1)
-                                       break;
-
-                               const u16 trisize = vc[i].tris.size();
-                               for (u16 t = 0; t < trisize; t++)
-                               {
-                                       tcache *tri = &tc[vc[i].tris[t]];
-
-                                       tri->score =
-                                               vc[tri->ind[0]].score +
-                                               vc[tri->ind[1]].score +
-                                               vc[tri->ind[2]].score;
-
-                                       if (tri->score > hiscore)
-                                       {
-                                               hiscore = tri->score;
-                                               highest = vc[i].tris[t];
-                                       }
-                               }
-                       }
-               }
-
-               return highest;
-       }
-
-private:
-       s32 cache[cachesize];
-       vcache *vc;
-       tcache *tc;
-};
-
-/**
-Vertex cache optimization according to the Forsyth paper:
-http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
-
-The function is thread-safe (read: you can optimize several meshes in different threads)
-
-\param mesh Source mesh for the operation.  */
-scene::IMesh* createForsythOptimizedMesh(const scene::IMesh *mesh)
-{
-       if (!mesh)
-               return 0;
-
-       scene::SMesh *newmesh = new scene::SMesh();
-       newmesh->BoundingBox = mesh->getBoundingBox();
-
-       const u32 mbcount = mesh->getMeshBufferCount();
-
-       for (u32 b = 0; b < mbcount; ++b)
-       {
-               const scene::IMeshBuffer *mb = mesh->getMeshBuffer(b);
-
-               if (mb->getIndexType() != video::EIT_16BIT)
-               {
-                       //os::Printer::log("Cannot optimize a mesh with 32bit indices", ELL_ERROR);
-                       newmesh->drop();
-                       return 0;
-               }
-
-               const u32 icount = mb->getIndexCount();
-               const u32 tcount = icount / 3;
-               const u32 vcount = mb->getVertexCount();
-               const u16 *ind = mb->getIndices();
-
-               vcache *vc = new vcache[vcount];
-               tcache *tc = new tcache[tcount];
-
-               f_lru lru(vc, tc);
-
-               // init
-               for (u16 i = 0; i < vcount; i++)
-               {
-                       vc[i].score = 0;
-                       vc[i].cachepos = -1;
-                       vc[i].NumActiveTris = 0;
-               }
-
-               // First pass: count how many times a vert is used
-               for (u32 i = 0; i < icount; i += 3)
-               {
-                       vc[ind[i]].NumActiveTris++;
-                       vc[ind[i + 1]].NumActiveTris++;
-                       vc[ind[i + 2]].NumActiveTris++;
-
-                       const u32 tri_ind = i/3;
-                       tc[tri_ind].ind[0] = ind[i];
-                       tc[tri_ind].ind[1] = ind[i + 1];
-                       tc[tri_ind].ind[2] = ind[i + 2];
-               }
-
-               // Second pass: list of each triangle
-               for (u32 i = 0; i < tcount; i++)
-               {
-                       vc[tc[i].ind[0]].tris.push_back(i);
-                       vc[tc[i].ind[1]].tris.push_back(i);
-                       vc[tc[i].ind[2]].tris.push_back(i);
-
-                       tc[i].drawn = false;
-               }
-
-               // Give initial scores
-               for (u16 i = 0; i < vcount; i++)
-               {
-                       vc[i].score = FindVertexScore(&vc[i]);
-               }
-               for (u32 i = 0; i < tcount; i++)
-               {
-                       tc[i].score =
-                                       vc[tc[i].ind[0]].score +
-                                       vc[tc[i].ind[1]].score +
-                                       vc[tc[i].ind[2]].score;
-               }
-
-               switch(mb->getVertexType())
-               {
-                       case video::EVT_STANDARD:
-                       {
-                               video::S3DVertex *v = (video::S3DVertex *) mb->getVertices();
-
-                               scene::SMeshBuffer *buf = new scene::SMeshBuffer();
-                               buf->Material = mb->getMaterial();
-
-                               buf->Vertices.reallocate(vcount);
-                               buf->Indices.reallocate(icount);
-
-                               core::map<const video::S3DVertex, const u16> sind; // search index for fast operation
-                               typedef core::map<const video::S3DVertex, const u16>::Node snode;
-
-                               // Main algorithm
-                               u32 highest = 0;
-                               u32 drawcalls = 0;
-                               for (;;)
-                               {
-                                       if (tc[highest].drawn)
-                                       {
-                                               bool found = false;
-                                               float hiscore = 0;
-                                               for (u32 t = 0; t < tcount; t++)
-                                               {
-                                                       if (!tc[t].drawn)
-                                                       {
-                                                               if (tc[t].score > hiscore)
-                                                               {
-                                                                       highest = t;
-                                                                       hiscore = tc[t].score;
-                                                                       found = true;
-                                                               }
-                                                       }
-                                               }
-                                               if (!found)
-                                                       break;
-                                       }
-
-                                       // Output the best triangle
-                                       u16 newind = buf->Vertices.size();
-
-                                       snode *s = sind.find(v[tc[highest].ind[0]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[0]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[0]], newind);
-                                               newind++;
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       s = sind.find(v[tc[highest].ind[1]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[1]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[1]], newind);
-                                               newind++;
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       s = sind.find(v[tc[highest].ind[2]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[2]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[2]], newind);
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       vc[tc[highest].ind[0]].NumActiveTris--;
-                                       vc[tc[highest].ind[1]].NumActiveTris--;
-                                       vc[tc[highest].ind[2]].NumActiveTris--;
-
-                                       tc[highest].drawn = true;
-
-                                       for (u16 j : tc[highest].ind) {
-                                               vcache *vert = &vc[j];
-                                               for (u16 t = 0; t < vert->tris.size(); t++)
-                                               {
-                                                       if (highest == vert->tris[t])
-                                                       {
-                                                               vert->tris.erase(t);
-                                                               break;
-                                                       }
-                                               }
-                                       }
-
-                                       lru.add(tc[highest].ind[0]);
-                                       lru.add(tc[highest].ind[1]);
-                                       highest = lru.add(tc[highest].ind[2], true);
-                                       drawcalls++;
-                               }
-
-                               buf->setBoundingBox(mb->getBoundingBox());
-                               newmesh->addMeshBuffer(buf);
-                               buf->drop();
-                       }
-                       break;
-                       case video::EVT_2TCOORDS:
-                       {
-                               video::S3DVertex2TCoords *v = (video::S3DVertex2TCoords *) mb->getVertices();
-
-                               scene::SMeshBufferLightMap *buf = new scene::SMeshBufferLightMap();
-                               buf->Material = mb->getMaterial();
-
-                               buf->Vertices.reallocate(vcount);
-                               buf->Indices.reallocate(icount);
-
-                               core::map<const video::S3DVertex2TCoords, const u16> sind; // search index for fast operation
-                               typedef core::map<const video::S3DVertex2TCoords, const u16>::Node snode;
-
-                               // Main algorithm
-                               u32 highest = 0;
-                               u32 drawcalls = 0;
-                               for (;;)
-                               {
-                                       if (tc[highest].drawn)
-                                       {
-                                               bool found = false;
-                                               float hiscore = 0;
-                                               for (u32 t = 0; t < tcount; t++)
-                                               {
-                                                       if (!tc[t].drawn)
-                                                       {
-                                                               if (tc[t].score > hiscore)
-                                                               {
-                                                                       highest = t;
-                                                                       hiscore = tc[t].score;
-                                                                       found = true;
-                                                               }
-                                                       }
-                                               }
-                                               if (!found)
-                                                       break;
-                                       }
-
-                                       // Output the best triangle
-                                       u16 newind = buf->Vertices.size();
-
-                                       snode *s = sind.find(v[tc[highest].ind[0]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[0]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[0]], newind);
-                                               newind++;
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       s = sind.find(v[tc[highest].ind[1]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[1]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[1]], newind);
-                                               newind++;
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       s = sind.find(v[tc[highest].ind[2]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[2]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[2]], newind);
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       vc[tc[highest].ind[0]].NumActiveTris--;
-                                       vc[tc[highest].ind[1]].NumActiveTris--;
-                                       vc[tc[highest].ind[2]].NumActiveTris--;
-
-                                       tc[highest].drawn = true;
-
-                                       for (u16 j : tc[highest].ind) {
-                                               vcache *vert = &vc[j];
-                                               for (u16 t = 0; t < vert->tris.size(); t++)
-                                               {
-                                                       if (highest == vert->tris[t])
-                                                       {
-                                                               vert->tris.erase(t);
-                                                               break;
-                                                       }
-                                               }
-                                       }
-
-                                       lru.add(tc[highest].ind[0]);
-                                       lru.add(tc[highest].ind[1]);
-                                       highest = lru.add(tc[highest].ind[2]);
-                                       drawcalls++;
-                               }
-
-                               buf->setBoundingBox(mb->getBoundingBox());
-                               newmesh->addMeshBuffer(buf);
-                               buf->drop();
-
-                       }
-                       break;
-                       case video::EVT_TANGENTS:
-                       {
-                               video::S3DVertexTangents *v = (video::S3DVertexTangents *) mb->getVertices();
-
-                               scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
-                               buf->Material = mb->getMaterial();
-
-                               buf->Vertices.reallocate(vcount);
-                               buf->Indices.reallocate(icount);
-
-                               core::map<const video::S3DVertexTangents, const u16> sind; // search index for fast operation
-                               typedef core::map<const video::S3DVertexTangents, const u16>::Node snode;
-
-                               // Main algorithm
-                               u32 highest = 0;
-                               u32 drawcalls = 0;
-                               for (;;)
-                               {
-                                       if (tc[highest].drawn)
-                                       {
-                                               bool found = false;
-                                               float hiscore = 0;
-                                               for (u32 t = 0; t < tcount; t++)
-                                               {
-                                                       if (!tc[t].drawn)
-                                                       {
-                                                               if (tc[t].score > hiscore)
-                                                               {
-                                                                       highest = t;
-                                                                       hiscore = tc[t].score;
-                                                                       found = true;
-                                                               }
-                                                       }
-                                               }
-                                               if (!found)
-                                                       break;
-                                       }
-
-                                       // Output the best triangle
-                                       u16 newind = buf->Vertices.size();
-
-                                       snode *s = sind.find(v[tc[highest].ind[0]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[0]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[0]], newind);
-                                               newind++;
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       s = sind.find(v[tc[highest].ind[1]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[1]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[1]], newind);
-                                               newind++;
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       s = sind.find(v[tc[highest].ind[2]]);
-
-                                       if (!s)
-                                       {
-                                               buf->Vertices.push_back(v[tc[highest].ind[2]]);
-                                               buf->Indices.push_back(newind);
-                                               sind.insert(v[tc[highest].ind[2]], newind);
-                                       }
-                                       else
-                                       {
-                                               buf->Indices.push_back(s->getValue());
-                                       }
-
-                                       vc[tc[highest].ind[0]].NumActiveTris--;
-                                       vc[tc[highest].ind[1]].NumActiveTris--;
-                                       vc[tc[highest].ind[2]].NumActiveTris--;
-
-                                       tc[highest].drawn = true;
-
-                                       for (u16 j : tc[highest].ind) {
-                                               vcache *vert = &vc[j];
-                                               for (u16 t = 0; t < vert->tris.size(); t++)
-                                               {
-                                                       if (highest == vert->tris[t])
-                                                       {
-                                                               vert->tris.erase(t);
-                                                               break;
-                                                       }
-                                               }
-                                       }
-
-                                       lru.add(tc[highest].ind[0]);
-                                       lru.add(tc[highest].ind[1]);
-                                       highest = lru.add(tc[highest].ind[2]);
-                                       drawcalls++;
-                               }
-
-                               buf->setBoundingBox(mb->getBoundingBox());
-                               newmesh->addMeshBuffer(buf);
-                               buf->drop();
-                       }
-                       break;
-               }
-
-               delete [] vc;
-               delete [] tc;
-
-       } // for each meshbuffer
-
-       return newmesh;
-}
index dbc091a06fd716ca64987ab5752d9f77d3fd717c..1ed753c0134101eba9eb4c7579ced9722ee7278d 100644 (file)
@@ -133,10 +133,3 @@ void recalculateBoundingBox(scene::IMesh *src_mesh);
        We assume normal to be valid when it's 0 < length < Inf. and not NaN
  */
 bool checkMeshNormals(scene::IMesh *mesh);
-
-/*
-       Vertex cache optimization according to the Forsyth paper:
-       http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
-       Ported from irrlicht 1.8
-*/
-scene::IMesh* createForsythOptimizedMesh(const scene::IMesh *mesh);
index c8d1cba2654fb7c3ef04f843c6d989f6cf412e5e..5c3f4180bb32d7136955ab8b8b6e2e352ffb701e 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client.h"
 #include "mapblock.h"
 #include "map.h"
+#include "util/directiontables.h"
 
 /*
        CachedMapBlockData
@@ -69,7 +70,7 @@ MeshUpdateQueue::~MeshUpdateQueue()
        }
 }
 
-void MeshUpdateQueue::addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent)
+bool MeshUpdateQueue::addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent)
 {
        MutexAutoLock lock(m_mutex);
 
@@ -81,20 +82,15 @@ void MeshUpdateQueue::addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool
        */
        std::vector<CachedMapBlockData*> cached_blocks;
        size_t cache_hit_counter = 0;
+       CachedMapBlockData *cached_block = cacheBlock(map, p, FORCE_UPDATE);
+       if (!cached_block->data)
+               return false; // nothing to update
        cached_blocks.reserve(3*3*3);
-       v3s16 dp;
-       for (dp.X = -1; dp.X <= 1; dp.X++)
-       for (dp.Y = -1; dp.Y <= 1; dp.Y++)
-       for (dp.Z = -1; dp.Z <= 1; dp.Z++) {
-               v3s16 p1 = p + dp;
-               CachedMapBlockData *cached_block;
-               if (dp == v3s16(0, 0, 0))
-                       cached_block = cacheBlock(map, p1, FORCE_UPDATE);
-               else
-                       cached_block = cacheBlock(map, p1, SKIP_UPDATE_IF_ALREADY_CACHED,
-                                       &cache_hit_counter);
-               cached_blocks.push_back(cached_block);
-       }
+       cached_blocks.push_back(cached_block);
+       for (v3s16 dp : g_26dirs)
+               cached_blocks.push_back(cacheBlock(map, p + dp,
+                               SKIP_UPDATE_IF_ALREADY_CACHED,
+                               &cache_hit_counter));
        g_profiler->avg("MeshUpdateQueue: MapBlocks from cache [%]",
                        100.0f * cache_hit_counter / cached_blocks.size());
 
@@ -116,7 +112,7 @@ void MeshUpdateQueue::addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool
                                q->ack_block_to_server = true;
                        q->crack_level = m_client->getCrackLevel();
                        q->crack_pos = m_client->getCrackPos();
-                       return;
+                       return true;
                }
        }
 
@@ -134,6 +130,7 @@ void MeshUpdateQueue::addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool
        for (CachedMapBlockData *cached_block : cached_blocks) {
                cached_block->refcount_from_queue++;
        }
+       return true;
 }
 
 // Returned pointer must be deleted
@@ -212,10 +209,7 @@ void MeshUpdateQueue::fillDataFromMapBlockCache(QueuedMeshUpdate *q)
        std::time_t t_now = std::time(0);
 
        // Collect data for 3*3*3 blocks from cache
-       v3s16 dp;
-       for (dp.X = -1; dp.X <= 1; dp.X++)
-       for (dp.Y = -1; dp.Y <= 1; dp.Y++)
-       for (dp.Z = -1; dp.Z <= 1; dp.Z++) {
+       for (v3s16 dp : g_27dirs) {
                v3s16 p = q->p + dp;
                CachedMapBlockData *cached_block = getCachedBlock(p);
                if (cached_block) {
@@ -272,10 +266,25 @@ MeshUpdateThread::MeshUpdateThread(Client *client):
 }
 
 void MeshUpdateThread::updateBlock(Map *map, v3s16 p, bool ack_block_to_server,
-               bool urgent)
+               bool urgent, bool update_neighbors)
 {
-       // Allow the MeshUpdateQueue to do whatever it wants
-       m_queue_in.addBlock(map, p, ack_block_to_server, urgent);
+       static thread_local const bool many_neighbors =
+                       g_settings->getBool("smooth_lighting")
+                       && !g_settings->getFlag("performance_tradeoffs");
+       if (!m_queue_in.addBlock(map, p, ack_block_to_server, urgent)) {
+               warningstream << "Update requested for non-existent block at ("
+                               << p.X << ", " << p.Y << ", " << p.Z << ")" << std::endl;
+               return;
+       }
+       if (update_neighbors) {
+               if (many_neighbors) {
+                       for (v3s16 dp : g_26dirs)
+                               m_queue_in.addBlock(map, p + dp, false, urgent);
+               } else {
+                       for (v3s16 dp : g_6dirs)
+                               m_queue_in.addBlock(map, p + dp, false, urgent);
+               }
+       }
        deferUpdate();
 }
 
index f393e2368ba66fb92e63c24d9c4645ed460d8d16..2ef69595449b8d519b1c9608a7f5c2d148ebfe32 100644 (file)
@@ -66,7 +66,7 @@ class MeshUpdateQueue
 
        // Caches the block at p and its neighbors (if needed) and queues a mesh
        // update for the block at p
-       void addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
+       bool addBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
 
        // Returned pointer must be deleted
        // Returns NULL if queue is empty
@@ -113,7 +113,8 @@ class MeshUpdateThread : public UpdateThread
 
        // Caches the block at p and its neighbors (if needed) and queues a mesh
        // update for the block at p
-       void updateBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent);
+       void updateBlock(Map *map, v3s16 p, bool ack_block_to_server, bool urgent,
+                       bool update_neighbors = false);
 
        v3s16 m_camera_offset;
        MutexedQueue<MeshUpdateResult> m_queue_out;
index 3013e140668d2eca42578d9b7c15d8722e1ecc04..9bb9d14e0ff5c2e513450aaa7451350dc642a835 100644 (file)
@@ -304,7 +304,7 @@ void Minimap::setModeIndex(size_t index)
                data->mode = m_modes[index];
                m_current_mode_index = index;
        } else {
-               data->mode = MinimapModeDef{MINIMAP_TYPE_OFF, gettext("Minimap hidden"), 0, 0, ""};
+               data->mode = {MINIMAP_TYPE_OFF, gettext("Minimap hidden"), 0, 0, "", 0};
                m_current_mode_index = 0;
        }
 
index 153e774002afac89a499095d9bdb14fedb775fb7..2571f7333bfd1458b71ddaa64ea37da5327d2945 100644 (file)
@@ -30,6 +30,7 @@ void RenderingCoreAnaglyph::drawAll()
 void RenderingCoreAnaglyph::setupMaterial(int color_mask)
 {
        video::SOverrideMaterial &mat = driver->getOverrideMaterial();
+       mat.reset();
        mat.Material.ColorMask = color_mask;
        mat.EnableFlags = video::EMF_COLOR_MASK;
        mat.EnablePasses = scene::ESNRP_SKY_BOX | scene::ESNRP_SOLID |
index 1028a96e140a5619b15cda7b0b41e7e03cc2d93d..9927e2589a97208c066ee85d6b621bdcbea15e78 100644 (file)
@@ -90,8 +90,11 @@ void RenderingCore::draw(video::SColor _skycolor, bool _show_hud, bool _show_min
        entity_esp_color = video::SColor(255, entity_color.X, entity_color.Y, entity_color.Z);
        player_esp_color = video::SColor(255, player_color.X, player_color.Y, player_color.Z);
 
-       if (shadow_renderer)
+       if (shadow_renderer) {
+               // This is necessary to render shadows for animations correctly
+               smgr->getRootSceneNode()->OnAnimate(device->getTimer()->getTime());
                shadow_renderer->update();
+       }
 
        beforeDraw();
        drawAll();
index 2e4994a40123f0dfcac5c357d82ebb9b2862ba1a..6ebcc784d151abd0ccb7fecc6ec38fbf07dc096c 100644 (file)
@@ -116,7 +116,7 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
        }
 
        SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
-       if (g_logger.getTraceEnabled())
+       if (tracestream)
                params.LoggingLevel = irr::ELL_DEBUG;
        params.DriverType = driverType;
        params.WindowSize = core::dimension2d<u32>(screen_w, screen_h);
@@ -597,7 +597,7 @@ static float calcDisplayDensity()
 float RenderingEngine::getDisplayDensity()
 {
        static float cached_display_density = calcDisplayDensity();
-       return cached_display_density;
+       return cached_display_density * g_settings->getFloat("display_density_factor");
 }
 
 #elif defined(_WIN32)
@@ -625,14 +625,14 @@ float RenderingEngine::getDisplayDensity()
                display_density = calcDisplayDensity(get_video_driver());
                cached = true;
        }
-       return display_density;
+       return display_density * g_settings->getFloat("display_density_factor");
 }
 
 #else
 
 float RenderingEngine::getDisplayDensity()
 {
-       return g_settings->getFloat("screen_dpi") / 96.0;
+       return (g_settings->getFloat("screen_dpi") / 96.0) * g_settings->getFloat("display_density_factor");
 }
 
 #endif
index dc9e9ae6d64a3b9bdaa939c65bc787a51ba20110..bbb8727612862810c0fb91fde47236773a4cf7be 100644 (file)
@@ -40,20 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client/tile.h"
 #include "config.h"
 
-#if ENABLE_GLES
-#ifdef _IRR_COMPILE_WITH_OGLES1_
-#include <GLES/gl.h>
-#else
-#include <GLES2/gl2.h>
-#endif
-#else
-#ifndef __APPLE__
-#include <GL/gl.h>
-#else
-#define GL_SILENCE_DEPRECATION
-#include <OpenGL/gl.h>
-#endif
-#endif
+#include <mt_opengl.h>
 
 /*
        A cache from shader name to shader path
@@ -223,17 +210,24 @@ class ShaderCallback : public video::IShaderConstantSetCallBack
 
 class MainShaderConstantSetter : public IShaderConstantSetter
 {
-       CachedVertexShaderSetting<float, 16> m_world_view_proj;
-       CachedVertexShaderSetting<float, 16> m_world;
+       CachedVertexShaderSetting<f32, 16> m_world_view_proj;
+       CachedVertexShaderSetting<f32, 16> m_world;
 
        // Shadow-related
-       CachedPixelShaderSetting<float, 16> m_shadow_view_proj;
-       CachedPixelShaderSetting<float, 3> m_light_direction;
-       CachedPixelShaderSetting<float> m_texture_res;
-       CachedPixelShaderSetting<float> m_shadow_strength;
-       CachedPixelShaderSetting<float> m_time_of_day;
-       CachedPixelShaderSetting<float> m_shadowfar;
+       CachedPixelShaderSetting<f32, 16> m_shadow_view_proj;
+       CachedPixelShaderSetting<f32, 3> m_light_direction;
+       CachedPixelShaderSetting<f32> m_texture_res;
+       CachedPixelShaderSetting<f32> m_shadow_strength;
+       CachedPixelShaderSetting<f32> m_time_of_day;
+       CachedPixelShaderSetting<f32> m_shadowfar;
+       CachedPixelShaderSetting<f32, 4> m_camera_pos;
        CachedPixelShaderSetting<s32> m_shadow_texture;
+       CachedVertexShaderSetting<f32> m_perspective_bias0_vertex;
+       CachedPixelShaderSetting<f32> m_perspective_bias0_pixel;
+       CachedVertexShaderSetting<f32> m_perspective_bias1_vertex;
+       CachedPixelShaderSetting<f32> m_perspective_bias1_pixel;
+       CachedVertexShaderSetting<f32> m_perspective_zbias_vertex;
+       CachedPixelShaderSetting<f32> m_perspective_zbias_pixel;
 
 #if ENABLE_GLES
        // Modelview matrix
@@ -248,18 +242,25 @@ class MainShaderConstantSetter : public IShaderConstantSetter
        MainShaderConstantSetter() :
                  m_world_view_proj("mWorldViewProj")
                , m_world("mWorld")
-#if ENABLE_GLES
-               , m_world_view("mWorldView")
-               , m_texture("mTexture")
-               , m_normal("mNormal")
-#endif
                , m_shadow_view_proj("m_ShadowViewProj")
                , m_light_direction("v_LightDirection")
                , m_texture_res("f_textureresolution")
                , m_shadow_strength("f_shadow_strength")
                , m_time_of_day("f_timeofday")
                , m_shadowfar("f_shadowfar")
+               , m_camera_pos("CameraPos")
                , m_shadow_texture("ShadowMapSampler")
+               , m_perspective_bias0_vertex("xyPerspectiveBias0")
+               , m_perspective_bias0_pixel("xyPerspectiveBias0")
+               , m_perspective_bias1_vertex("xyPerspectiveBias1")
+               , m_perspective_bias1_pixel("xyPerspectiveBias1")
+               , m_perspective_zbias_vertex("zPerspectiveBias")
+               , m_perspective_zbias_pixel("zPerspectiveBias")
+#if ENABLE_GLES
+               , m_world_view("mWorldView")
+               , m_texture("mTexture")
+               , m_normal("mNormal")
+#endif
        {}
        ~MainShaderConstantSetter() = default;
 
@@ -306,26 +307,40 @@ class MainShaderConstantSetter : public IShaderConstantSetter
                        shadowViewProj *= light.getViewMatrix();
                        m_shadow_view_proj.set(shadowViewProj.pointer(), services);
 
-                       float v_LightDirection[3];
+                       f32 v_LightDirection[3];
                        light.getDirection().getAs3Values(v_LightDirection);
                        m_light_direction.set(v_LightDirection, services);
 
-                       float TextureResolution = light.getMapResolution();
+                       f32 TextureResolution = light.getMapResolution();
                        m_texture_res.set(&TextureResolution, services);
 
-                       float ShadowStrength = shadow->getShadowStrength();
+                       f32 ShadowStrength = shadow->getShadowStrength();
                        m_shadow_strength.set(&ShadowStrength, services);
 
-                       float timeOfDay = shadow->getTimeOfDay();
+                       f32 timeOfDay = shadow->getTimeOfDay();
                        m_time_of_day.set(&timeOfDay, services);
 
-                       float shadowFar = shadow->getMaxShadowFar();
+                       f32 shadowFar = shadow->getMaxShadowFar();
                        m_shadowfar.set(&shadowFar, services);
 
+                       f32 cam_pos[4];
+                       shadowViewProj.transformVect(cam_pos, light.getPlayerPos());
+                       m_camera_pos.set(cam_pos, services);
+
                        // I dont like using this hardcoded value. maybe something like
                        // MAX_TEXTURE - 1 or somthing like that??
                        s32 TextureLayerID = 3;
                        m_shadow_texture.set(&TextureLayerID, services);
+
+                       f32 bias0 = shadow->getPerspectiveBiasXY();
+                       m_perspective_bias0_vertex.set(&bias0, services);
+                       m_perspective_bias0_pixel.set(&bias0, services);
+                       f32 bias1 = 1.0f - bias0 + 1e-5f;
+                       m_perspective_bias1_vertex.set(&bias1, services);
+                       m_perspective_bias1_pixel.set(&bias1, services);
+                       f32 zbias = shadow->getPerspectiveBiasZ();
+                       m_perspective_zbias_vertex.set(&zbias, services);
+                       m_perspective_zbias_pixel.set(&zbias, services);
                }
        }
 };
@@ -667,13 +682,19 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
                )";
        }
 
+       // Since this is the first time we're using the GL bindings be extra careful.
+       // This should be removed before 5.6.0 or similar.
+       if (!GL.GetString) {
+               errorstream << "OpenGL procedures were not loaded correctly, "
+                       "please open a bug report with details about your platform/OS." << std::endl;
+               abort();
+       }
+
        bool use_discard = use_gles;
-#ifdef __unix__
        // For renderers that should use discard instead of GL_ALPHA_TEST
-       const char* gl_renderer = (const char*)glGetString(GL_RENDERER);
-       if (strstr(gl_renderer, "GC7000"))
+       const char *renderer = reinterpret_cast<const char*>(GL.GetString(GL.RENDERER));
+       if (strstr(renderer, "GC7000"))
                use_discard = true;
-#endif
        if (use_discard) {
                if (shaderinfo.base_material == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
                        shaders_header << "#define USE_DISCARD 1\n";
index 0c7eea0e74339a6a39a71615f596645c8652ba3e..ca2d3ce379954e6d0dce6f96629c838fbcd8e26c 100644 (file)
@@ -29,7 +29,6 @@ using m4f = core::matrix4;
 
 void DirectionalLight::createSplitMatrices(const Camera *cam)
 {
-       float radius;
        v3f newCenter;
        v3f look = cam->getDirection();
 
@@ -42,59 +41,38 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
        float sfFar = adjustDist(future_frustum.zFar, cam->getFovY());
 
        // adjusted camera positions
-       v3f camPos2 = cam->getPosition();
-       v3f camPos = v3f(camPos2.X - cam->getOffset().X * BS,
-                       camPos2.Y - cam->getOffset().Y * BS,
-                       camPos2.Z - cam->getOffset().Z * BS);
-       camPos += look * sfNear;
-       camPos2 += look * sfNear;
+       v3f cam_pos_world = cam->getPosition();
+       v3f cam_pos_scene = v3f(cam_pos_world.X - cam->getOffset().X * BS,
+                       cam_pos_world.Y - cam->getOffset().Y * BS,
+                       cam_pos_world.Z - cam->getOffset().Z * BS);
+       cam_pos_scene += look * sfNear;
+       cam_pos_world += look * sfNear;
 
        // center point of light frustum
-       float end = sfNear + sfFar;
-       newCenter = camPos + look * (sfNear + 0.05f * end);
-       v3f world_center = camPos2 + look * (sfNear + 0.05f * end);
+       v3f center_scene = cam_pos_scene + look * 0.35 * (sfFar - sfNear);
+       v3f center_world = cam_pos_world + look * 0.35 * (sfFar - sfNear);
 
        // Create a vector to the frustum far corner
        const v3f &viewUp = cam->getCameraNode()->getUpVector();
        v3f viewRight = look.crossProduct(viewUp);
 
-       v3f farCorner = look + viewRight * tanFovX + viewUp * tanFovY;
+       v3f farCorner = (look + viewRight * tanFovX + viewUp * tanFovY).normalize();
        // Compute the frustumBoundingSphere radius
-       v3f boundVec = (camPos + farCorner * sfFar) - newCenter;
-       radius = boundVec.getLength() * 2.0f;
-       // boundVec.getLength();
-       float vvolume = radius * 2.0f;
-
-       float texelsPerUnit = getMapResolution() / vvolume;
-       m4f mTexelScaling;
-       mTexelScaling.setScale(texelsPerUnit);
-
-       m4f mLookAt, mLookAtInv;
-
-       mLookAt.buildCameraLookAtMatrixLH(v3f(0.0f, 0.0f, 0.0f), -direction, v3f(0.0f, 1.0f, 0.0f));
-
-       mLookAt *= mTexelScaling;
-       mLookAtInv = mLookAt;
-       mLookAtInv.makeInverse();
-
-       v3f frustumCenter = newCenter;
-       mLookAt.transformVect(frustumCenter);
-       frustumCenter.X = floorf(frustumCenter.X); // clamp to texel increment
-       frustumCenter.Y = floorf(frustumCenter.Y); // clamp to texel increment
-       frustumCenter.Z = floorf(frustumCenter.Z);
-       mLookAtInv.transformVect(frustumCenter);
-       // probar radius multipliacdor en funcion del I, a menor I mas multiplicador
-       v3f eye_displacement = direction * vvolume;
+       v3f boundVec = (cam_pos_scene + farCorner * sfFar) - center_scene;
+       float radius = boundVec.getLength();
+       float length = radius * 3.0f;
+       v3f eye_displacement = direction * length;
 
        // we must compute the viewmat with the position - the camera offset
        // but the future_frustum position must be the actual world position
-       v3f eye = frustumCenter - eye_displacement;
-       future_frustum.position = world_center - eye_displacement;
-       future_frustum.length = vvolume;
-       future_frustum.ViewMat.buildCameraLookAtMatrixLH(eye, frustumCenter, v3f(0.0f, 1.0f, 0.0f));
-       future_frustum.ProjOrthMat.buildProjectionMatrixOrthoLH(future_frustum.length,
-                       future_frustum.length, -future_frustum.length,
-                       future_frustum.length,false);
+       v3f eye = center_scene - eye_displacement;
+       future_frustum.player = cam_pos_scene;
+       future_frustum.position = center_world - eye_displacement;
+       future_frustum.length = length;
+       future_frustum.radius = radius;
+       future_frustum.ViewMat.buildCameraLookAtMatrixLH(eye, center_scene, v3f(0.0f, 1.0f, 0.0f));
+       future_frustum.ProjOrthMat.buildProjectionMatrixOrthoLH(radius, radius, 
+                       0.0f, length, false);
        future_frustum.camera_offset = cam->getOffset();
 }
 
@@ -112,6 +90,8 @@ void DirectionalLight::update_frustum(const Camera *cam, Client *client, bool fo
 
        float zNear = cam->getCameraNode()->getNearValue();
        float zFar = getMaxFarValue();
+       if (!client->getEnv().getClientMap().getControl().range_all)
+               zFar = MYMIN(zFar, client->getEnv().getClientMap().getControl().wanted_range * BS);
 
        ///////////////////////////////////
        // update splits near and fars
@@ -122,7 +102,7 @@ void DirectionalLight::update_frustum(const Camera *cam, Client *client, bool fo
        createSplitMatrices(cam);
        // get the draw list for shadows
        client->getEnv().getClientMap().updateDrawListShadow(
-                       getPosition(), getDirection(), future_frustum.length);
+                       getPosition(), getDirection(), future_frustum.radius, future_frustum.length);
        should_update_map_shadow = true;
        dirty = true;
 
@@ -132,6 +112,7 @@ void DirectionalLight::update_frustum(const Camera *cam, Client *client, bool fo
                v3f rotated_offset;
                shadow_frustum.ViewMat.rotateVect(rotated_offset, intToFloat(cam_offset - shadow_frustum.camera_offset, BS));
                shadow_frustum.ViewMat.setTranslation(shadow_frustum.ViewMat.getTranslation() + rotated_offset);
+               shadow_frustum.player += intToFloat(shadow_frustum.camera_offset - cam->getOffset(), BS);
                shadow_frustum.camera_offset = cam_offset;
        }
 }
@@ -156,6 +137,16 @@ v3f DirectionalLight::getPosition() const
        return shadow_frustum.position;
 }
 
+v3f DirectionalLight::getPlayerPos() const
+{
+       return shadow_frustum.player;
+}
+
+v3f DirectionalLight::getFuturePlayerPos() const
+{
+       return future_frustum.player;
+}
+
 const m4f &DirectionalLight::getViewMatrix() const
 {
        return shadow_frustum.ViewMat;
index d8be66be89bd67032d289553666c12060a647fa5..6e9d96b157c89ea10c54592f07890e8ddbf703db 100644 (file)
@@ -22,18 +22,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes_bloated.h"
 #include <matrix4.h>
 #include "util/basic_macros.h"
+#include "constants.h"
 
 class Camera;
 class Client;
 
 struct shadowFrustum
 {
-       float zNear{0.0f};
-       float zFar{0.0f};
-       float length{0.0f};
+       f32 zNear{0.0f};
+       f32 zFar{0.0f};
+       f32 length{0.0f};
+       f32 radius{0.0f};
        core::matrix4 ProjOrthMat;
        core::matrix4 ViewMat;
        v3f position;
+       v3f player;
        v3s16 camera_offset;
 };
 
@@ -56,6 +59,8 @@ class DirectionalLight
                return direction;
        };
        v3f getPosition() const;
+       v3f getPlayerPos() const;
+       v3f getFuturePlayerPos() const;
 
        /// Gets the light's matrices.
        const core::matrix4 &getViewMatrix() const;
@@ -64,10 +69,16 @@ class DirectionalLight
        const core::matrix4 &getFutureProjectionMatrix() const;
        core::matrix4 getViewProjMatrix();
 
-       /// Gets the light's far value.
+       /// Gets the light's maximum far value, i.e. the shadow boundary
        f32 getMaxFarValue() const
        {
-               return farPlane;
+               return farPlane * BS;
+       }
+
+       /// Gets the current far value of the light
+       f32 getFarValue() const
+       {
+               return shadow_frustum.zFar;
        }
 
 
index a913a9290af468a8210c516ebf646146891281bf..07dc6daf265595b6bcba690b9f976bf2c5d77687 100644 (file)
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include <cstring>
+#include <cmath>
 #include "client/shadows/dynamicshadowsrender.h"
 #include "client/shadows/shadowsScreenQuad.h"
 #include "client/shadows/shadowsshadercallbacks.h"
@@ -30,12 +31,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "profiler.h"
 
 ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
-               m_device(device), m_smgr(device->getSceneManager()),
-               m_driver(device->getVideoDriver()), m_client(client), m_current_frame(0)
+               m_smgr(device->getSceneManager()), m_driver(device->getVideoDriver()),
+               m_client(client), m_current_frame(0),
+               m_perspective_bias_xy(0.8), m_perspective_bias_z(0.5)
 {
+       (void) m_client;
+
+       m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize
        m_shadows_enabled = true;
 
-       m_shadow_strength = g_settings->getFloat("shadow_strength");
+       m_shadow_strength_gamma = g_settings->getFloat("shadow_strength_gamma");
+       if (std::isnan(m_shadow_strength_gamma))
+               m_shadow_strength_gamma = 1.0f;
+       m_shadow_strength_gamma = core::clamp(m_shadow_strength_gamma, 0.1f, 10.0f);
 
        m_shadow_map_max_distance = g_settings->getFloat("shadow_map_max_distance");
 
@@ -49,8 +57,15 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
 
 ShadowRenderer::~ShadowRenderer()
 {
+       // call to disable releases dynamically allocated resources
+       disable();
+
        if (m_shadow_depth_cb)
                delete m_shadow_depth_cb;
+       if (m_shadow_depth_entity_cb)
+               delete m_shadow_depth_entity_cb;
+       if (m_shadow_depth_trans_cb)
+               delete m_shadow_depth_trans_cb;
        if (m_shadow_mix_cb)
                delete m_shadow_mix_cb;
        m_shadow_node_array.clear();
@@ -72,15 +87,25 @@ ShadowRenderer::~ShadowRenderer()
                m_driver->removeTexture(shadowMapClientMapFuture);
 }
 
+void ShadowRenderer::disable()
+{
+       m_shadows_enabled = false;
+       if (shadowMapTextureFinal) {
+               m_driver->setRenderTarget(shadowMapTextureFinal, true, true,
+                       video::SColor(255, 255, 255, 255));
+               m_driver->setRenderTarget(0, true, true);
+       }
+}
+
 void ShadowRenderer::initialize()
 {
        auto *gpu = m_driver->getGPUProgrammingServices();
 
        // we need glsl
-       if (m_shadows_enabled && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) {
+       if (m_shadows_supported && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) {
                createShaders();
        } else {
-               m_shadows_enabled = false;
+               m_shadows_supported = false;
 
                warningstream << "Shadows: GLSL Shader not supported on this system."
                        << std::endl;
@@ -94,6 +119,8 @@ void ShadowRenderer::initialize()
        m_texture_format_color = m_shadow_map_texture_32bit
                                                 ? video::ECOLOR_FORMAT::ECF_G32R32F
                                                 : video::ECOLOR_FORMAT::ECF_G16R16F;
+       
+       m_shadows_enabled &= m_shadows_supported;
 }
 
 
@@ -118,16 +145,21 @@ size_t ShadowRenderer::getDirectionalLightCount() const
 f32 ShadowRenderer::getMaxShadowFar() const
 {
        if (!m_light_list.empty()) {
-               float wanted_range = m_client->getEnv().getClientMap().getWantedRange();
-
-               float zMax = m_light_list[0].getMaxFarValue() > wanted_range
-                                            ? wanted_range
-                                            : m_light_list[0].getMaxFarValue();
-               return zMax * MAP_BLOCKSIZE;
+               float zMax = m_light_list[0].getFarValue();
+               return zMax;
        }
        return 0.0f;
 }
 
+void ShadowRenderer::setShadowIntensity(float shadow_intensity)
+{
+       m_shadow_strength = pow(shadow_intensity, 1.0f / m_shadow_strength_gamma);
+       if (m_shadow_strength > 1E-2)
+               enable();
+       else
+               disable();
+}
+
 void ShadowRenderer::addNodeToShadowList(
                scene::ISceneNode *node, E_SHADOW_MODE shadowMode)
 {
@@ -157,6 +189,7 @@ void ShadowRenderer::updateSMTextures()
                shadowMapTextureDynamicObjects = getSMTexture(
                        std::string("shadow_dynamic_") + itos(m_shadow_map_texture_size),
                        m_texture_format, true);
+               assert(shadowMapTextureDynamicObjects != nullptr);
        }
 
        if (!shadowMapClientMap) {
@@ -165,6 +198,7 @@ void ShadowRenderer::updateSMTextures()
                        std::string("shadow_clientmap_") + itos(m_shadow_map_texture_size),
                        m_shadow_map_colored ? m_texture_format_color : m_texture_format,
                        true);
+               assert(shadowMapClientMap != nullptr);
        }
 
        if (!shadowMapClientMapFuture && m_map_shadow_update_frames > 1) {
@@ -172,6 +206,7 @@ void ShadowRenderer::updateSMTextures()
                        std::string("shadow_clientmap_bb_") + itos(m_shadow_map_texture_size),
                        m_shadow_map_colored ? m_texture_format_color : m_texture_format,
                        true);
+               assert(shadowMapClientMapFuture != nullptr);
        }
 
        if (m_shadow_map_colored && !shadowMapTextureColors) {
@@ -179,6 +214,7 @@ void ShadowRenderer::updateSMTextures()
                        std::string("shadow_colored_") + itos(m_shadow_map_texture_size),
                        m_shadow_map_colored ? m_texture_format_color : m_texture_format,
                        true);
+               assert(shadowMapTextureColors != nullptr);
        }
 
        // The merge all shadowmaps texture
@@ -198,6 +234,7 @@ void ShadowRenderer::updateSMTextures()
                shadowMapTextureFinal = getSMTexture(
                        std::string("shadowmap_final_") + itos(m_shadow_map_texture_size),
                        frt, true);
+               assert(shadowMapTextureFinal != nullptr);
        }
 
        if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
@@ -219,9 +256,15 @@ void ShadowRenderer::updateSMTextures()
                // Update SM incrementally:
                for (DirectionalLight &light : m_light_list) {
                        // Static shader values.
-                       m_shadow_depth_cb->MapRes = (f32)m_shadow_map_texture_size;
-                       m_shadow_depth_cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
-
+                       for (auto cb : {m_shadow_depth_cb, m_shadow_depth_entity_cb, m_shadow_depth_trans_cb})
+                               if (cb) {
+                                       cb->MapRes = (f32)m_shadow_map_texture_size;
+                                       cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
+                                       cb->PerspectiveBiasXY = getPerspectiveBiasXY();
+                                       cb->PerspectiveBiasZ = getPerspectiveBiasZ();
+                                       cb->CameraPos = light.getFuturePlayerPos();
+                               }
+                       
                        // set the Render Target
                        // right now we can only render in usual RTT, not
                        // Depth texture is available in irrlicth maybe we
@@ -274,12 +317,17 @@ void ShadowRenderer::update(video::ITexture *outputTarget)
 
        updateSMTextures();
 
+       if (shadowMapTextureFinal == nullptr) {
+               return;
+       }
+
        if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
 
                for (DirectionalLight &light : m_light_list) {
-                       // Static shader values.
-                       m_shadow_depth_cb->MapRes = (f32)m_shadow_map_texture_size;
-                       m_shadow_depth_cb->MaxFar = (f32)m_shadow_map_max_distance * BS;
+                       // Static shader values for entities are set in updateSMTextures
+                       // SM texture for entities is not updated incrementally and 
+                       // must by updated using current player position.
+                       m_shadow_depth_entity_cb->CameraPos = light.getPlayerPos();
 
                        // render shadows for the n0n-map objects.
                        m_driver->setRenderTarget(shadowMapTextureDynamicObjects, true,
@@ -311,19 +359,23 @@ void ShadowRenderer::drawDebug()
        /* this code just shows shadows textures in screen and in ONLY for debugging*/
        #if 0
        // this is debug, ignore for now.
-       m_driver->draw2DImage(shadowMapTextureFinal,
-                       core::rect<s32>(0, 50, 128, 128 + 50),
-                       core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
+       if (shadowMapTextureFinal)
+               m_driver->draw2DImage(shadowMapTextureFinal,
+                               core::rect<s32>(0, 50, 128, 128 + 50),
+                               core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
 
-       m_driver->draw2DImage(shadowMapClientMap,
-                       core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128),
-                       core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
-       m_driver->draw2DImage(shadowMapTextureDynamicObjects,
-                       core::rect<s32>(0, 128 + 50 + 128, 128,
-                                       128 + 50 + 128 + 128),
-                       core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize()));
+       if (shadowMapClientMap)
+               m_driver->draw2DImage(shadowMapClientMap,
+                               core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128),
+                               core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
+       
+       if (shadowMapTextureDynamicObjects)
+               m_driver->draw2DImage(shadowMapTextureDynamicObjects,
+                               core::rect<s32>(0, 128 + 50 + 128, 128,
+                                               128 + 50 + 128 + 128),
+                               core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize()));
 
-       if (m_shadow_map_colored) {
+       if (m_shadow_map_colored && shadowMapTextureColors) {
 
                m_driver->draw2DImage(shadowMapTextureColors,
                                core::rect<s32>(128,128 + 50 + 128 + 128,
@@ -368,10 +420,6 @@ void ShadowRenderer::renderShadowMap(video::ITexture *target,
 
                material.BackfaceCulling = false;
                material.FrontfaceCulling = true;
-               material.PolygonOffsetFactor = 4.0f;
-               material.PolygonOffsetDirection = video::EPO_BACK;
-               //material.PolygonOffsetDepthBias = 1.0f/4.0f;
-               //material.PolygonOffsetSlopeScale = -1.f;
 
                if (m_shadow_map_colored && pass != scene::ESNRP_SOLID) {
                        material.MaterialType = (video::E_MATERIAL_TYPE) depth_shader_trans;
@@ -381,9 +429,6 @@ void ShadowRenderer::renderShadowMap(video::ITexture *target,
                        material.BlendOperation = video::EBO_MIN;
                }
 
-               // FIXME: I don't think this is needed here
-               map_node->OnAnimate(m_device->getTimer()->getTime());
-
                m_driver->setTransform(video::ETS_WORLD,
                                map_node->getAbsoluteTransformation());
 
@@ -429,10 +474,6 @@ void ShadowRenderer::renderShadowObjects(
 
                        current_mat.BackfaceCulling = true;
                        current_mat.FrontfaceCulling = false;
-                       current_mat.PolygonOffsetFactor = 1.0f/2048.0f;
-                       current_mat.PolygonOffsetDirection = video::EPO_BACK;
-                       //current_mat.PolygonOffsetDepthBias = 1.0 * 2.8e-6;
-                       //current_mat.PolygonOffsetSlopeScale = -1.f;
                }
 
                m_driver->setTransform(video::ETS_WORLD,
@@ -473,13 +514,13 @@ void ShadowRenderer::createShaders()
        if (depth_shader == -1) {
                std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
                if (depth_shader_vs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error shadow mapping vs shader not found." << std::endl;
                        return;
                }
                std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
                if (depth_shader_fs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error shadow mapping fs shader not found." << std::endl;
                        return;
                }
@@ -494,7 +535,9 @@ void ShadowRenderer::createShaders()
                if (depth_shader == -1) {
                        // upsi, something went wrong loading shader.
                        delete m_shadow_depth_cb;
+                       m_shadow_depth_cb = nullptr;
                        m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error compiling shadow mapping shader." << std::endl;
                        return;
                }
@@ -510,26 +553,30 @@ void ShadowRenderer::createShaders()
        if (depth_shader_entities == -1) {
                std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
                if (depth_shader_vs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error shadow mapping vs shader not found." << std::endl;
                        return;
                }
                std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
                if (depth_shader_fs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error shadow mapping fs shader not found." << std::endl;
                        return;
                }
+               m_shadow_depth_entity_cb = new ShadowDepthShaderCB();
 
                depth_shader_entities = gpu->addHighLevelShaderMaterial(
                                readShaderFile(depth_shader_vs).c_str(), "vertexMain",
                                video::EVST_VS_1_1,
                                readShaderFile(depth_shader_fs).c_str(), "pixelMain",
-                               video::EPST_PS_1_2, m_shadow_depth_cb);
+                               video::EPST_PS_1_2, m_shadow_depth_entity_cb);
 
                if (depth_shader_entities == -1) {
                        // upsi, something went wrong loading shader.
+                       delete m_shadow_depth_entity_cb;
+                       m_shadow_depth_entity_cb = nullptr;
                        m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error compiling shadow mapping shader (dynamic)." << std::endl;
                        return;
                }
@@ -543,14 +590,14 @@ void ShadowRenderer::createShaders()
        if (mixcsm_shader == -1) {
                std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass2_vertex.glsl");
                if (depth_shader_vs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
                        return;
                }
 
                std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass2_fragment.glsl");
                if (depth_shader_fs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
                        return;
                }
@@ -569,7 +616,7 @@ void ShadowRenderer::createShaders()
                        // upsi, something went wrong loading shader.
                        delete m_shadow_mix_cb;
                        delete m_screen_quad;
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error compiling cascade shadow mapping shader." << std::endl;
                        return;
                }
@@ -583,13 +630,13 @@ void ShadowRenderer::createShaders()
        if (m_shadow_map_colored && depth_shader_trans == -1) {
                std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_trans_vertex.glsl");
                if (depth_shader_vs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error shadow mapping vs shader not found." << std::endl;
                        return;
                }
                std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_trans_fragment.glsl");
                if (depth_shader_fs.empty()) {
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error shadow mapping fs shader not found." << std::endl;
                        return;
                }
@@ -604,8 +651,9 @@ void ShadowRenderer::createShaders()
                if (depth_shader_trans == -1) {
                        // upsi, something went wrong loading shader.
                        delete m_shadow_depth_trans_cb;
+                       m_shadow_depth_trans_cb = nullptr;
                        m_shadow_map_colored = false;
-                       m_shadows_enabled = false;
+                       m_shadows_supported = false;
                        errorstream << "Error compiling colored shadow mapping shader." << std::endl;
                        return;
                }
index e4b3c3e220e213bc74bd9576a9b79d07d2d3162b..0e4ef6b70cd29ee220845531cf2a6644db2c0832 100644 (file)
@@ -82,13 +82,17 @@ class ShadowRenderer
        }
 
 
-       bool is_active() const { return m_shadows_enabled; }
+       bool is_active() const { return m_shadows_enabled && shadowMapTextureFinal != nullptr; }
        void setTimeOfDay(float isDay) { m_time_day = isDay; };
+       void setShadowIntensity(float shadow_intensity);
 
        s32 getShadowSamples() const { return m_shadow_samples; }
-       float getShadowStrength() const { return m_shadow_strength; }
+       float getShadowStrength() const { return m_shadows_enabled ? m_shadow_strength : 0.0f; }
        float getTimeOfDay() const { return m_time_day; }
 
+       f32 getPerspectiveBiasXY() { return m_perspective_bias_xy; }
+       f32 getPerspectiveBiasZ() { return m_perspective_bias_z; }
+
 private:
        video::ITexture *getSMTexture(const std::string &shadow_map_name,
                        video::ECOLOR_FORMAT texture_format,
@@ -101,8 +105,10 @@ class ShadowRenderer
        void mixShadowsQuad();
        void updateSMTextures();
 
+       void disable();
+       void enable() { m_shadows_enabled = m_shadows_supported; }
+
        // a bunch of variables
-       IrrlichtDevice *m_device{nullptr};
        scene::ISceneManager *m_smgr{nullptr};
        video::IVideoDriver *m_driver{nullptr};
        Client *m_client{nullptr};
@@ -116,15 +122,19 @@ class ShadowRenderer
        std::vector<NodeToApply> m_shadow_node_array;
 
        float m_shadow_strength;
+       float m_shadow_strength_gamma;
        float m_shadow_map_max_distance;
        float m_shadow_map_texture_size;
        float m_time_day{0.0f};
        int m_shadow_samples;
        bool m_shadow_map_texture_32bit;
        bool m_shadows_enabled;
+       bool m_shadows_supported;
        bool m_shadow_map_colored;
        u8 m_map_shadow_update_frames; /* Use this number of frames to update map shaodw */
        u8 m_current_frame{0}; /* Current frame */
+       f32 m_perspective_bias_xy;
+       f32 m_perspective_bias_z;
 
        video::ECOLOR_FORMAT m_texture_format{video::ECOLOR_FORMAT::ECF_R16F};
        video::ECOLOR_FORMAT m_texture_format_color{video::ECOLOR_FORMAT::ECF_R16G16};
@@ -140,6 +150,7 @@ class ShadowRenderer
        s32 mixcsm_shader{-1};
 
        ShadowDepthShaderCB *m_shadow_depth_cb{nullptr};
+       ShadowDepthShaderCB *m_shadow_depth_entity_cb{nullptr};
        ShadowDepthShaderCB *m_shadow_depth_trans_cb{nullptr};
 
        shadowScreenQuad *m_screen_quad{nullptr};
index 65a63f49c7b4eb5ad44d2cf7cfe2da58a82d8fa8..b571ea9391ab7235dcf0480f13d663e4d6def754 100644 (file)
@@ -26,6 +26,10 @@ void ShadowDepthShaderCB::OnSetConstants(
 
        core::matrix4 lightMVP = driver->getTransform(video::ETS_PROJECTION);
        lightMVP *= driver->getTransform(video::ETS_VIEW);
+
+       f32 cam_pos[4];
+       lightMVP.transformVect(cam_pos, CameraPos);
+
        lightMVP *= driver->getTransform(video::ETS_WORLD);
 
        m_light_mvp_setting.set(lightMVP.pointer(), services);
@@ -33,4 +37,12 @@ void ShadowDepthShaderCB::OnSetConstants(
        m_max_far_setting.set(&MaxFar, services);
        s32 TextureId = 0;
        m_color_map_sampler_setting.set(&TextureId, services);
+       f32 bias0 = PerspectiveBiasXY;
+       m_perspective_bias0.set(&bias0, services);
+       f32 bias1 = 1.0f - bias0 + 1e-5f;
+       m_perspective_bias1.set(&bias1, services);
+       f32 zbias = PerspectiveBiasZ;
+       m_perspective_zbias.set(&zbias, services);
+
+       m_cam_pos_setting.set(cam_pos, services);
 }
index 3549567c3ef5031c58f7a1369e57bd66cfeecef3..87833c0ec4ecaf1ba0ed61aa31f14d7477c3ba85 100644 (file)
@@ -30,7 +30,11 @@ class ShadowDepthShaderCB : public video::IShaderConstantSetCallBack
                        m_light_mvp_setting("LightMVP"),
                        m_map_resolution_setting("MapResolution"),
                        m_max_far_setting("MaxFar"),
-                       m_color_map_sampler_setting("ColorMapSampler")
+                       m_color_map_sampler_setting("ColorMapSampler"),
+                       m_perspective_bias0("xyPerspectiveBias0"),
+                       m_perspective_bias1("xyPerspectiveBias1"),
+                       m_perspective_zbias("zPerspectiveBias"),
+                       m_cam_pos_setting("CameraPos")
        {}
 
        void OnSetMaterial(const video::SMaterial &material) override {}
@@ -39,10 +43,16 @@ class ShadowDepthShaderCB : public video::IShaderConstantSetCallBack
                        s32 userData) override;
 
        f32 MaxFar{2048.0f}, MapRes{1024.0f};
+       f32 PerspectiveBiasXY {0.9f}, PerspectiveBiasZ {0.5f};
+       v3f CameraPos;
 
 private:
        CachedVertexShaderSetting<f32, 16> m_light_mvp_setting;
        CachedVertexShaderSetting<f32> m_map_resolution_setting;
        CachedVertexShaderSetting<f32> m_max_far_setting;
        CachedPixelShaderSetting<s32> m_color_map_sampler_setting;
+       CachedVertexShaderSetting<f32> m_perspective_bias0;
+       CachedVertexShaderSetting<f32> m_perspective_bias1;
+       CachedVertexShaderSetting<f32> m_perspective_zbias;
+       CachedVertexShaderSetting<f32, 4> m_cam_pos_setting;
 };
index 1cf9a4afca3b43cc442582d435e62f9bd4604905..0ab710eee1d138bcc415e22c2c7c574b310cf783 100644 (file)
@@ -18,21 +18,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include <cmath>
 #include "sky.h"
-#include "ITexture.h"
-#include "IVideoDriver.h"
-#include "ISceneManager.h"
-#include "ICameraSceneNode.h"
-#include "S3DVertex.h"
+#include <ITexture.h>
+#include <IVideoDriver.h>
+#include <ISceneManager.h>
+#include <ICameraSceneNode.h>
+#include <S3DVertex.h>
 #include "client/tile.h"
 #include "noise.h" // easeCurve
 #include "profiler.h"
 #include "util/numeric.h"
-#include <cmath>
 #include "client/renderingengine.h"
 #include "settings.h"
 #include "camera.h" // CameraModes
-#include "config.h"
+
 using namespace irr::core;
 
 static video::SMaterial baseMaterial()
@@ -51,7 +51,14 @@ static video::SMaterial baseMaterial()
        mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
        mat.BackfaceCulling = false;
        return mat;
-};
+}
+
+static inline void disableTextureFiltering(video::SMaterial &mat)
+{
+       mat.setFlag(video::E_MATERIAL_FLAG::EMF_BILINEAR_FILTER, false);
+       mat.setFlag(video::E_MATERIAL_FLAG::EMF_TRILINEAR_FILTER, false);
+       mat.setFlag(video::E_MATERIAL_FLAG::EMF_ANISOTROPIC_FILTER, false);
+}
 
 Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShaderSource *ssrc) :
                scene::ISceneNode(rendering_engine->get_scene_manager()->getRootSceneNode(),
@@ -65,6 +72,11 @@ Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShade
 
        m_enable_shaders = g_settings->getBool("enable_shaders");
 
+       m_sky_params = SkyboxDefaults::getSkyDefaults();
+       m_sun_params = SkyboxDefaults::getSunDefaults();
+       m_moon_params = SkyboxDefaults::getMoonDefaults();
+       m_star_params = SkyboxDefaults::getStarDefaults();
+
        // Create materials
 
        m_materials[0] = baseMaterial();
@@ -73,49 +85,15 @@ Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShade
        m_materials[0].ColorMaterial = video::ECM_NONE;
 
        m_materials[1] = baseMaterial();
-       //m_materials[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
        m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
 
        m_materials[2] = baseMaterial();
        m_materials[2].setTexture(0, tsrc->getTextureForMesh("sunrisebg.png"));
        m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-       //m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
-
-       // Ensures that sun and moon textures and tonemaps are correct.
-       setSkyDefaults();
-       m_sun_texture = tsrc->isKnownSourceImage(m_sun_params.texture) ?
-               tsrc->getTextureForMesh(m_sun_params.texture) : nullptr;
-       m_moon_texture = tsrc->isKnownSourceImage(m_moon_params.texture) ?
-               tsrc->getTextureForMesh(m_moon_params.texture) : nullptr;
-       m_sun_tonemap = tsrc->isKnownSourceImage(m_sun_params.tonemap) ?
-               tsrc->getTexture(m_sun_params.tonemap) : nullptr;
-       m_moon_tonemap = tsrc->isKnownSourceImage(m_moon_params.tonemap) ?
-               tsrc->getTexture(m_moon_params.tonemap) : nullptr;
 
-       if (m_sun_texture) {
-               m_materials[3] = baseMaterial();
-               m_materials[3].setTexture(0, m_sun_texture);
-               m_materials[3].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-               // Disables texture filtering
-               m_materials[3].setFlag(video::E_MATERIAL_FLAG::EMF_BILINEAR_FILTER, false);
-               m_materials[3].setFlag(video::E_MATERIAL_FLAG::EMF_TRILINEAR_FILTER, false);
-               m_materials[3].setFlag(video::E_MATERIAL_FLAG::EMF_ANISOTROPIC_FILTER, false);
-               // Use tonemaps if available
-               if (m_sun_tonemap)
-                       m_materials[3].Lighting = true;
-       }
-       if (m_moon_texture) {
-               m_materials[4] = baseMaterial();
-               m_materials[4].setTexture(0, m_moon_texture);
-               m_materials[4].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-               // Disables texture filtering
-               m_materials[4].setFlag(video::E_MATERIAL_FLAG::EMF_BILINEAR_FILTER, false);
-               m_materials[4].setFlag(video::E_MATERIAL_FLAG::EMF_TRILINEAR_FILTER, false);
-               m_materials[4].setFlag(video::E_MATERIAL_FLAG::EMF_ANISOTROPIC_FILTER, false);
-               // Use tonemaps if available
-               if (m_moon_tonemap)
-                       m_materials[4].Lighting = true;
-       }
+       setSunTexture(m_sun_params.texture, m_sun_params.tonemap, tsrc);
+
+       setMoonTexture(m_moon_params.texture, m_moon_params.tonemap, tsrc);
 
        for (int i = 5; i < 11; i++) {
                m_materials[i] = baseMaterial();
@@ -130,7 +108,7 @@ Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShade
                m_sky_body_orbit_tilt = rangelim(val, 0.0f, 60.0f);
        }
 
-       setStarCount(1000, true);
+       setStarCount(1000);
 }
 
 void Sky::OnRegisterSceneNode()
@@ -386,20 +364,6 @@ void Sky::update(float time_of_day, float time_brightness,
 
        bool is_dawn = (time_brightness >= 0.20 && time_brightness < 0.35);
 
-       /*
-       Development colours
-
-       video::SColorf bgcolor_bright_normal_f(170. / 255, 200. / 255, 230. / 255, 1.0);
-       video::SColorf bgcolor_bright_dawn_f(0.666, 200. / 255 * 0.7, 230. / 255 * 0.5, 1.0);
-       video::SColorf bgcolor_bright_dawn_f(0.666, 0.549, 0.220, 1.0);
-       video::SColorf bgcolor_bright_dawn_f(0.666 * 1.2, 0.549 * 1.0, 0.220 * 1.0, 1.0);
-       video::SColorf bgcolor_bright_dawn_f(0.666 * 1.2, 0.549 * 1.0, 0.220 * 1.2, 1.0);
-
-       video::SColorf cloudcolor_bright_dawn_f(1.0, 0.591, 0.4);
-       video::SColorf cloudcolor_bright_dawn_f(1.0, 0.65, 0.44);
-       video::SColorf cloudcolor_bright_dawn_f(1.0, 0.7, 0.5);
-       */
-
        video::SColorf bgcolor_bright_normal_f = m_sky_params.sky_color.day_horizon;
        video::SColorf bgcolor_bright_indoor_f = m_sky_params.sky_color.indoors;
        video::SColorf bgcolor_bright_dawn_f = m_sky_params.sky_color.dawn_horizon;
@@ -754,33 +718,29 @@ void Sky::setSunTexture(const std::string &sun_texture,
        // Ignore matching textures (with modifiers) entirely,
        // but lets at least update the tonemap before hand.
        m_sun_params.tonemap = sun_tonemap;
-       m_sun_tonemap = tsrc->isKnownSourceImage(m_sun_params.tonemap) ?
-               tsrc->getTexture(m_sun_params.tonemap) : nullptr;
+       m_sun_tonemap = tsrc->isKnownSourceImage(sun_tonemap) ?
+               tsrc->getTexture(sun_tonemap) : nullptr;
        m_materials[3].Lighting = !!m_sun_tonemap;
 
-       if (m_sun_params.texture == sun_texture)
+       if (m_sun_params.texture == sun_texture && !m_first_update)
                return;
        m_sun_params.texture = sun_texture;
 
-       if (sun_texture != "") {
-               // We want to ensure the texture exists first.
-               m_sun_texture = tsrc->getTextureForMesh(m_sun_params.texture);
-
-               if (m_sun_texture) {
-                       m_materials[3] = baseMaterial();
-                       m_materials[3].setTexture(0, m_sun_texture);
-                       m_materials[3].MaterialType = video::
-                               EMT_TRANSPARENT_ALPHA_CHANNEL;
-                       // Disables texture filtering
-                       m_materials[3].setFlag(
-                               video::E_MATERIAL_FLAG::EMF_BILINEAR_FILTER, false);
-                       m_materials[3].setFlag(
-                               video::E_MATERIAL_FLAG::EMF_TRILINEAR_FILTER, false);
-                       m_materials[3].setFlag(
-                               video::E_MATERIAL_FLAG::EMF_ANISOTROPIC_FILTER, false);
-               }
-       } else {
-               m_sun_texture = nullptr;
+       m_sun_texture = nullptr;
+       if (sun_texture == "sun.png") {
+               // Dumb compatibility fix: sun.png transparently falls back to no texture
+               m_sun_texture = tsrc->isKnownSourceImage(sun_texture) ?
+                       tsrc->getTexture(sun_texture) : nullptr;
+       } else if (!sun_texture.empty()) {
+               m_sun_texture = tsrc->getTextureForMesh(sun_texture);
+       }
+
+       if (m_sun_texture) {
+               m_materials[3] = baseMaterial();
+               m_materials[3].setTexture(0, m_sun_texture);
+               m_materials[3].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+               disableTextureFiltering(m_materials[3]);
+               m_materials[3].Lighting = !!m_sun_tonemap;
        }
 }
 
@@ -802,40 +762,36 @@ void Sky::setMoonTexture(const std::string &moon_texture,
        // Ignore matching textures (with modifiers) entirely,
        // but lets at least update the tonemap before hand.
        m_moon_params.tonemap = moon_tonemap;
-       m_moon_tonemap = tsrc->isKnownSourceImage(m_moon_params.tonemap) ?
-               tsrc->getTexture(m_moon_params.tonemap) : nullptr;
+       m_moon_tonemap = tsrc->isKnownSourceImage(moon_tonemap) ?
+               tsrc->getTexture(moon_tonemap) : nullptr;
        m_materials[4].Lighting = !!m_moon_tonemap;
 
-       if (m_moon_params.texture == moon_texture)
+       if (m_moon_params.texture == moon_texture && !m_first_update)
                return;
        m_moon_params.texture = moon_texture;
 
-       if (moon_texture != "") {
-               // We want to ensure the texture exists first.
-               m_moon_texture = tsrc->getTextureForMesh(m_moon_params.texture);
-
-               if (m_moon_texture) {
-                       m_materials[4] = baseMaterial();
-                       m_materials[4].setTexture(0, m_moon_texture);
-                       m_materials[4].MaterialType = video::
-                               EMT_TRANSPARENT_ALPHA_CHANNEL;
-                       // Disables texture filtering
-                       m_materials[4].setFlag(
-                               video::E_MATERIAL_FLAG::EMF_BILINEAR_FILTER, false);
-                       m_materials[4].setFlag(
-                               video::E_MATERIAL_FLAG::EMF_TRILINEAR_FILTER, false);
-                       m_materials[4].setFlag(
-                               video::E_MATERIAL_FLAG::EMF_ANISOTROPIC_FILTER, false);
-               }
-       } else {
-               m_moon_texture = nullptr;
+       m_moon_texture = nullptr;
+       if (moon_texture == "moon.png") {
+               // Dumb compatibility fix: moon.png transparently falls back to no texture
+               m_moon_texture = tsrc->isKnownSourceImage(moon_texture) ?
+                       tsrc->getTexture(moon_texture) : nullptr;
+       } else if (!moon_texture.empty()) {
+               m_moon_texture = tsrc->getTextureForMesh(moon_texture);
+       }
+
+       if (m_moon_texture) {
+               m_materials[4] = baseMaterial();
+               m_materials[4].setTexture(0, m_moon_texture);
+               m_materials[4].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+               disableTextureFiltering(m_materials[4]);
+               m_materials[4].Lighting = !!m_moon_tonemap;
        }
 }
 
-void Sky::setStarCount(u16 star_count, bool force_update)
+void Sky::setStarCount(u16 star_count)
 {
        // Allow force updating star count at game init.
-       if (m_star_params.count != star_count || force_update) {
+       if (m_star_params.count != star_count || m_first_update) {
                m_star_params.count = star_count;
                updateStars();
        }
@@ -924,16 +880,6 @@ void Sky::addTextureToSkybox(const std::string &texture, int material_id,
        m_materials[material_id+5].MaterialType = video::EMT_SOLID;
 }
 
-// To be called once at game init to setup default values.
-void Sky::setSkyDefaults()
-{
-       SkyboxDefaults sky_defaults;
-       m_sky_params.sky_color = sky_defaults.getSkyColorDefaults();
-       m_sun_params = sky_defaults.getSunDefaults();
-       m_moon_params = sky_defaults.getMoonDefaults();
-       m_star_params = sky_defaults.getStarDefaults();
-}
-
 float getWickedTimeOfDay(float time_of_day)
 {
        float nightlength = 0.415f;
index 83106453b4af309d64ba58d7542912b23b8ea8b5..e03683f121a40a03c41689e12e3ac1ff50425df1 100644 (file)
@@ -17,6 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#pragma once
+
 #include "irrlichttypes_extrabloated.h"
 #include <ISceneNode.h>
 #include <array>
@@ -25,8 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "shader.h"
 #include "skyparams.h"
 
-#pragma once
-
 #define SKY_MATERIAL_COUNT 12
 
 class ITextureSource;
@@ -65,6 +65,7 @@ class Sky : public scene::ISceneNode
        }
 
        void setSunVisible(bool sun_visible) { m_sun_params.visible = sun_visible; }
+       bool getSunVisible() const { return m_sun_params.visible; }
        void setSunTexture(const std::string &sun_texture,
                const std::string &sun_tonemap, ITextureSource *tsrc);
        void setSunScale(f32 sun_scale) { m_sun_params.scale = sun_scale; }
@@ -72,12 +73,13 @@ class Sky : public scene::ISceneNode
        void setSunriseTexture(const std::string &sunglow_texture, ITextureSource* tsrc);
 
        void setMoonVisible(bool moon_visible) { m_moon_params.visible = moon_visible; }
+       bool getMoonVisible() const { return m_moon_params.visible; }
        void setMoonTexture(const std::string &moon_texture,
                const std::string &moon_tonemap, ITextureSource *tsrc);
        void setMoonScale(f32 moon_scale) { m_moon_params.scale = moon_scale; }
 
        void setStarsVisible(bool stars_visible) { m_star_params.visible = stars_visible; }
-       void setStarCount(u16 star_count, bool force_update);
+       void setStarCount(u16 star_count);
        void setStarColor(video::SColor star_color) { m_star_params.starcolor = star_color; }
        void setStarScale(f32 star_scale) { m_star_params.scale = star_scale; updateStars(); }
 
@@ -150,7 +152,7 @@ class Sky : public scene::ISceneNode
        bool m_visible = true;
        // Used when m_visible=false
        video::SColor m_fallback_bg_color = video::SColor(255, 255, 255, 255);
-       bool m_first_update = true;
+       bool m_first_update = true; // Set before the sky is updated for the first time
        float m_time_of_day;
        float m_time_brightness;
        bool m_sunlight_seen;
@@ -206,7 +208,6 @@ class Sky : public scene::ISceneNode
        void draw_stars(video::IVideoDriver *driver, float wicked_time_of_day);
        void place_sky_body(std::array<video::S3DVertex, 4> &vertices,
                float horizon_position, float day_position);
-       void setSkyDefaults();
 };
 
 // calculates value for sky body positions for the given observed time of day
index a31e3aca16b4783be167bff6a1cf02088d68fc84..aa78c50f01d412cadb8007acd76a5322a78355e0 100644 (file)
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "imagefilters.h"
 #include "guiscalingfilter.h"
 #include "renderingengine.h"
+#include "util/base64.h"
 
 /*
        A cache from texture name to texture path
@@ -762,6 +763,9 @@ void TextureSource::rebuildImagesAndTextures()
 
        // Recreate textures
        for (TextureInfo &ti : m_textureinfo_cache) {
+               if (ti.name.empty())
+                       continue; // Skip dummy entry
+
                video::IImage *img = generateImage(ti.name);
 #if ENABLE_GLES
                img = Align2Npot2(img, driver);
@@ -1056,6 +1060,45 @@ static std::string unescape_string(const std::string &str, const char esc = '\\'
        return out;
 }
 
+void blitBaseImage(video::IImage* &src, video::IImage* &dst)
+{
+       //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl;
+       // Size of the copied area
+       core::dimension2d<u32> dim = src->getDimension();
+       //core::dimension2d<u32> dim(16,16);
+       // Position to copy the blitted to in the base image
+       core::position2d<s32> pos_to(0,0);
+       // Position to copy the blitted from in the blitted image
+       core::position2d<s32> pos_from(0,0);
+       // Blit
+       /*image->copyToWithAlpha(baseimg, pos_to,
+                       core::rect<s32>(pos_from, dim),
+                       video::SColor(255,255,255,255),
+                       NULL);*/
+
+       core::dimension2d<u32> dim_dst = dst->getDimension();
+       if (dim == dim_dst) {
+               blit_with_alpha(src, dst, pos_from, pos_to, dim);
+       } else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) {
+               // Upscale overlying image
+               video::IImage *scaled_image = RenderingEngine::get_video_driver()->
+                       createImage(video::ECF_A8R8G8B8, dim_dst);
+               src->copyToScaling(scaled_image);
+
+               blit_with_alpha(scaled_image, dst, pos_from, pos_to, dim_dst);
+               scaled_image->drop();
+       } else {
+               // Upscale base image
+               video::IImage *scaled_base = RenderingEngine::get_video_driver()->
+                       createImage(video::ECF_A8R8G8B8, dim);
+               dst->copyToScaling(scaled_base);
+               dst->drop();
+               dst = scaled_base;
+
+               blit_with_alpha(src, dst, pos_from, pos_to, dim);
+       }
+}
+
 bool TextureSource::generateImagePart(std::string part_of_name,
                video::IImage *& baseimg)
 {
@@ -1066,9 +1109,6 @@ bool TextureSource::generateImagePart(std::string part_of_name,
        // Stuff starting with [ are special commands
        if (part_of_name.empty() || part_of_name[0] != '[') {
                video::IImage *image = m_sourcecache.getOrLoad(part_of_name);
-#if ENABLE_GLES
-               image = Align2Npot2(image, driver);
-#endif
                if (image == NULL) {
                        if (!part_of_name.empty()) {
 
@@ -1119,41 +1159,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
                // Else blit on base.
                else
                {
-                       //infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl;
-                       // Size of the copied area
-                       core::dimension2d<u32> dim = image->getDimension();
-                       //core::dimension2d<u32> dim(16,16);
-                       // Position to copy the blitted to in the base image
-                       core::position2d<s32> pos_to(0,0);
-                       // Position to copy the blitted from in the blitted image
-                       core::position2d<s32> pos_from(0,0);
-                       // Blit
-                       /*image->copyToWithAlpha(baseimg, pos_to,
-                                       core::rect<s32>(pos_from, dim),
-                                       video::SColor(255,255,255,255),
-                                       NULL);*/
-
-                       core::dimension2d<u32> dim_dst = baseimg->getDimension();
-                       if (dim == dim_dst) {
-                               blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
-                       } else if (dim.Width * dim.Height < dim_dst.Width * dim_dst.Height) {
-                               // Upscale overlying image
-                               video::IImage *scaled_image = RenderingEngine::get_video_driver()->
-                                       createImage(video::ECF_A8R8G8B8, dim_dst);
-                               image->copyToScaling(scaled_image);
-
-                               blit_with_alpha(scaled_image, baseimg, pos_from, pos_to, dim_dst);
-                               scaled_image->drop();
-                       } else {
-                               // Upscale base image
-                               video::IImage *scaled_base = RenderingEngine::get_video_driver()->
-                                       createImage(video::ECF_A8R8G8B8, dim);
-                               baseimg->copyToScaling(scaled_base);
-                               baseimg->drop();
-                               baseimg = scaled_base;
-
-                               blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
-                       }
+                       blitBaseImage(image, baseimg);
                }
                //cleanup
                image->drop();
@@ -1781,6 +1787,43 @@ bool TextureSource::generateImagePart(std::string part_of_name,
                        baseimg->drop();
                        baseimg = img;
                }
+               /*
+                       [png:base64
+                       Decodes a PNG image in base64 form.
+                       Use minetest.encode_png and minetest.encode_base64
+                       to produce a valid string.
+               */
+               else if (str_starts_with(part_of_name, "[png:")) {
+                       Strfnd sf(part_of_name);
+                       sf.next(":");
+                       std::string png;
+                       {
+                               std::string blob = sf.next("");
+                               if (!base64_is_valid(blob)) {
+                                       errorstream << "generateImagePart(): "
+                                                               << "malformed base64 in '[png'"
+                                                               << std::endl;
+                                       return false;
+                               }
+                               png = base64_decode(blob);
+                       }
+
+                       auto *device = RenderingEngine::get_raw_device();
+                       auto *fs = device->getFileSystem();
+                       auto *vd = device->getVideoDriver();
+                       auto *memfile = fs->createMemoryReadFile(png.data(), png.size(), "__temp_png");
+                       video::IImage* pngimg = vd->createImageFromFile(memfile);
+                       memfile->drop();
+
+                       if (baseimg) {
+                               blitBaseImage(pngimg, baseimg);
+                       } else {
+                               core::dimension2d<u32> dim = pngimg->getDimension();
+                               baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
+                               pngimg->copyTo(baseimg);
+                       }
+                       pngimg->drop();
+               }
                else
                {
                        errorstream << "generateImagePart(): Invalid "
@@ -2183,6 +2226,48 @@ video::ITexture* TextureSource::getNormalTexture(const std::string &name)
        return NULL;
 }
 
+namespace {
+       // For more colourspace transformations, see for example
+       // https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl
+
+       inline float linear_to_srgb_component(float v)
+       {
+               if (v > 0.0031308f)
+                       return 1.055f * powf(v, 1.0f / 2.4f) - 0.055f;
+               return 12.92f * v;
+       }
+       inline float srgb_to_linear_component(float v)
+       {
+               if (v > 0.04045f)
+                       return powf((v + 0.055f) / 1.055f, 2.4f);
+               return v / 12.92f;
+       }
+
+       v3f srgb_to_linear(const video::SColor &col_srgb)
+       {
+               v3f col(col_srgb.getRed(), col_srgb.getGreen(), col_srgb.getBlue());
+               col /= 255.0f;
+               col.X = srgb_to_linear_component(col.X);
+               col.Y = srgb_to_linear_component(col.Y);
+               col.Z = srgb_to_linear_component(col.Z);
+               return col;
+       }
+
+       video::SColor linear_to_srgb(const v3f &col_linear)
+       {
+               v3f col;
+               col.X = linear_to_srgb_component(col_linear.X);
+               col.Y = linear_to_srgb_component(col_linear.Y);
+               col.Z = linear_to_srgb_component(col_linear.Z);
+               col *= 255.0f;
+               col.X = core::clamp<float>(col.X, 0.0f, 255.0f);
+               col.Y = core::clamp<float>(col.Y, 0.0f, 255.0f);
+               col.Z = core::clamp<float>(col.Z, 0.0f, 255.0f);
+               return video::SColor(0xff, myround(col.X), myround(col.Y),
+                       myround(col.Z));
+       }
+}
+
 video::SColor TextureSource::getTextureAverageColor(const std::string &name)
 {
        video::IVideoDriver *driver = RenderingEngine::get_video_driver();
@@ -2197,9 +2282,7 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
                return c;
 
        u32 total = 0;
-       u32 tR = 0;
-       u32 tG = 0;
-       u32 tB = 0;
+       v3f col_acc(0, 0, 0);
        core::dimension2d<u32> dim = image->getDimension();
        u16 step = 1;
        if (dim.Width > 16)
@@ -2209,17 +2292,14 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
                        c = image->getPixel(x,y);
                        if (c.getAlpha() > 0) {
                                total++;
-                               tR += c.getRed();
-                               tG += c.getGreen();
-                               tB += c.getBlue();
+                               col_acc += srgb_to_linear(c);
                        }
                }
        }
        image->drop();
        if (total > 0) {
-               c.setRed(tR / total);
-               c.setGreen(tG / total);
-               c.setBlue(tB / total);
+               col_acc /= total;
+               c = linear_to_srgb(col_acc);
        }
        c.setAlpha(255);
        return c;
index fcdc46460ccfe542e1c9d0b830d7317e1ad2b4e1..e55a26e563f8e51cd0c2ad466d85b072a2480f82 100644 (file)
@@ -195,6 +195,7 @@ struct TileLayer
                        texture_id == other.texture_id &&
                        material_type == other.material_type &&
                        material_flags == other.material_flags &&
+                       has_color == other.has_color &&
                        color == other.color &&
                        scale == other.scale;
        }
@@ -259,6 +260,17 @@ struct TileLayer
                        && (material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL);
        }
 
+       bool isTransparent() const
+       {
+               switch (material_type) {
+               case TILE_MATERIAL_ALPHA:
+               case TILE_MATERIAL_LIQUID_TRANSPARENT:
+               case TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT:
+                       return true;
+               }
+               return false;
+       }
+
        // Ordered for size, please do not reorder
 
        video::ITexture *texture = nullptr;
@@ -288,9 +300,9 @@ struct TileLayer
         * The color of the tile, or if the tile does not own
         * a color then the color of the node owning this tile.
         */
-       video::SColor color;
+       video::SColor color = video::SColor(0, 0, 0, 0);
 
-       u8 scale;
+       u8 scale = 1;
 };
 
 /*!
@@ -307,7 +319,8 @@ struct TileSpec
                for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
                        if (layers[layer] != other.layers[layer])
                                return false;
-                       if (!layers[layer].isTileable())
+                       // Only non-transparent tiles can be merged into fast faces
+                       if (layers[layer].isTransparent() || !layers[layer].isTileable())
                                return false;
                }
                return rotation == 0
index 6beed3f3a4a0af5c190833b3abad3c047b57d072..25b34357386892c61d7e6ce4c6acd641f220ca80 100644 (file)
@@ -386,6 +386,9 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
                m_colors.emplace_back();
                // overlay is white, if present
                m_colors.emplace_back(true, video::SColor(0xFFFFFFFF));
+               // initialize the color
+               if (!m_lighting)
+                       setColor(video::SColor(0xFFFFFFFF));
                return;
        }
 
@@ -457,13 +460,26 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
                        material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter);
                        material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter);
                }
+
+               // initialize the color
+               if (!m_lighting)
+                       setColor(video::SColor(0xFFFFFFFF));
                return;
-       } else if (!def.inventory_image.empty()) {
-               setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale,
-                       tsrc, 1);
+       } else {
+               if (!def.inventory_image.empty()) {
+                       setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale,
+                               tsrc, 1);
+               } else {
+                       setExtruded("no_texture.png", "", def.wield_scale, tsrc, 1);
+               }
+
                m_colors.emplace_back();
                // overlay is white, if present
                m_colors.emplace_back(true, video::SColor(0xFFFFFFFF));
+
+               // initialize the color
+               if (!m_lighting)
+                       setColor(video::SColor(0xFFFFFFFF));
                return;
        }
 
@@ -510,8 +526,9 @@ void WieldMeshSceneNode::setNodeLightColor(video::SColor color)
                        material.EmissiveColor = color;
                }
        }
-
-       setColor(color);
+       else {
+               setColor(color);
+       }
 }
 
 void WieldMeshSceneNode::render()
@@ -536,9 +553,14 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh)
        m_meshnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, m_lighting);
        m_meshnode->setVisible(true);
 
-       // Add mesh to shadow caster
-       if (m_shadow)
+       if (m_shadow) {
+               // Add mesh to shadow caster
                m_shadow->addNodeToShadowList(m_meshnode);
+
+               // Set shadow texture
+               for (u32 i = 0; i < m_meshnode->getMaterialCount(); i++)
+                       m_meshnode->setMaterialTexture(3, m_shadow->get_texture());
+       }
 }
 
 void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
index f35dcd0ebf4e1da9dc0a3ea4c05e0bb55bed7eeb..5733b05def440d7df18bebbd2fe71979581a4e3c 100644 (file)
@@ -472,20 +472,14 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
                {
                case CSE_AuthAccept:
                        m_state = CS_AwaitingInit2;
-                       if (chosen_mech == AUTH_MECHANISM_SRP ||
-                                       chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD)
-                               srp_verifier_delete((SRPVerifier *) auth_data);
-                       chosen_mech = AUTH_MECHANISM_NONE;
+                       resetChosenMech();
                        break;
                case CSE_Disconnect:
                        m_state = CS_Disconnecting;
                        break;
                case CSE_SetDenied:
                        m_state = CS_Denied;
-                       if (chosen_mech == AUTH_MECHANISM_SRP ||
-                                       chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD)
-                               srp_verifier_delete((SRPVerifier *) auth_data);
-                       chosen_mech = AUTH_MECHANISM_NONE;
+                       resetChosenMech();
                        break;
                default:
                        myerror << "HelloSent: Invalid client state transition! " << event;
@@ -561,9 +555,7 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
                        break;
                case CSE_SudoSuccess:
                        m_state = CS_SudoMode;
-                       if (chosen_mech == AUTH_MECHANISM_SRP)
-                               srp_verifier_delete((SRPVerifier *) auth_data);
-                       chosen_mech = AUTH_MECHANISM_NONE;
+                       resetChosenMech();
                        break;
                /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */
                default:
@@ -596,6 +588,15 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
        }
 }
 
+void RemoteClient::resetChosenMech()
+{
+       if (auth_data) {
+               srp_verifier_delete((SRPVerifier *) auth_data);
+               auth_data = nullptr;
+       }
+       chosen_mech = AUTH_MECHANISM_NONE;
+}
+
 u64 RemoteClient::uptime() const
 {
        return porting::getTimeS() - m_connection_time;
@@ -714,31 +715,6 @@ void ClientInterface::sendToAll(NetworkPacket *pkt)
        }
 }
 
-void ClientInterface::sendToAllCompat(NetworkPacket *pkt, NetworkPacket *legacypkt,
-               u16 min_proto_ver)
-{
-       RecursiveMutexAutoLock clientslock(m_clients_mutex);
-       for (auto &client_it : m_clients) {
-               RemoteClient *client = client_it.second;
-               NetworkPacket *pkt_to_send = nullptr;
-
-               if (client->net_proto_version >= min_proto_ver) {
-                       pkt_to_send = pkt;
-               } else if (client->net_proto_version != 0) {
-                       pkt_to_send = legacypkt;
-               } else {
-                       warningstream << "Client with unhandled version to handle: '"
-                               << client->net_proto_version << "'";
-                       continue;
-               }
-
-               m_con->Send(client->peer_id,
-                       clientCommandFactoryTable[pkt_to_send->getCommand()].channel,
-                       pkt_to_send,
-                       clientCommandFactoryTable[pkt_to_send->getCommand()].reliable);
-       }
-}
-
 RemoteClient* ClientInterface::getClientNoEx(session_t peer_id, ClientState state_min)
 {
        RecursiveMutexAutoLock clientslock(m_clients_mutex);
index dfd97674137c249d0dcb6a3d7cdeba2152f0a9d1..3e7ba4793a77352554cca45c1240f23bee554baa 100644 (file)
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "network/networkprotocol.h"
 #include "network/address.h"
 #include "porting.h"
+#include "threading/mutex_auto_lock.h"
 
 #include <list>
 #include <vector>
@@ -242,6 +243,8 @@ class RemoteClient
        u32 allowed_auth_mechs = 0;
        u32 allowed_sudo_mechs = 0;
 
+       void resetChosenMech();
+
        bool isSudoMechAllowed(AuthMechanism mech)
        { return allowed_sudo_mechs & mech; }
        bool isMechAllowed(AuthMechanism mech)
@@ -340,7 +343,7 @@ class RemoteClient
        u8 getMinor() const { return m_version_minor; }
        u8 getPatch() const { return m_version_patch; }
        const std::string &getFullVer() const { return m_full_version; }
-       
+
        void setLangCode(const std::string &code) { m_lang_code = code; }
        const std::string &getLangCode() const { return m_lang_code; }
 
@@ -465,7 +468,6 @@ class ClientInterface {
 
        /* send to all clients */
        void sendToAll(NetworkPacket *pkt);
-       void sendToAllCompat(NetworkPacket *pkt, NetworkPacket *legacypkt, u16 min_proto_ver);
 
        /* delete a client */
        void DeleteClient(session_t peer_id);
@@ -504,9 +506,13 @@ class ClientInterface {
 
        static std::string state2Name(ClientState state);
 protected:
-       //TODO find way to avoid this functions
-       void lock() { m_clients_mutex.lock(); }
-       void unlock() { m_clients_mutex.unlock(); }
+       class AutoLock {
+       public:
+               AutoLock(ClientInterface &iface): m_lock(iface.m_clients_mutex) {}
+
+       private:
+               RecursiveMutexAutoLock m_lock;
+       };
 
        RemoteClientMap& getClientList() { return m_clients; }
 
diff --git a/src/cloudparams.h b/src/cloudparams.h
deleted file mode 100644 (file)
index 88b5760..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-Minetest
-Copyright (C) 2017 bendeutsch, Ben Deutsch <ben@bendeutsch.de>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#pragma once
-
-struct CloudParams
-{
-       float density;
-       video::SColor color_bright;
-       video::SColor color_ambient;
-       float thickness;
-       float height;
-       v2f speed;
-};
index cfcee4b5854cc6ccd278ab1b453f44681b326b2e..b1298165e4c06e557a340eb185354b0f43fc0aa3 100644 (file)
@@ -18,7 +18,6 @@
 #cmakedefine01 USE_GETTEXT
 #cmakedefine01 USE_CURL
 #cmakedefine01 USE_SOUND
-#cmakedefine01 USE_FREETYPE
 #cmakedefine01 USE_CURSES
 #cmakedefine01 USE_LEVELDB
 #cmakedefine01 USE_LUAJIT
@@ -36,3 +35,4 @@
 #cmakedefine01 CURSES_HAVE_NCURSESW_NCURSES_H
 #cmakedefine01 CURSES_HAVE_NCURSESW_CURSES_H
 #cmakedefine01 BUILD_UNITTESTS
+#cmakedefine01 BUILD_BENCHMARKS
index 2e788956de89889c805127a8e1c767ef9ae10e30..4f2cba2636d0b839b2ae5331d961b137e933f948 100644 (file)
@@ -153,7 +153,7 @@ CollisionAxis axisAlignedCollision(
                                                (std::max(movingbox.MaxEdge.Z + speed.Z * time, staticbox.MaxEdge.Z)
                                                        - std::min(movingbox.MinEdge.Z + speed.Z * time, staticbox.MinEdge.Z)
                                                        - relbox.MinEdge.Z < 0)
-                                       ) 
+                                       )
                                        return COLLISION_AXIS_X;
                        }
                } else {
@@ -180,7 +180,7 @@ CollisionAxis axisAlignedCollision(
                                                (std::max(movingbox.MaxEdge.Y + speed.Y * time, staticbox.MaxEdge.Y)
                                                        - std::min(movingbox.MinEdge.Y + speed.Y * time, staticbox.MinEdge.Y)
                                                        - relbox.MinEdge.Y < 0)
-                                       ) 
+                                       )
                                        return COLLISION_AXIS_Z;
                        }
                }
@@ -304,7 +304,8 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                        if (!(f.walkable || (jesus && f.isLiquid())))
                                continue;
 
-                       int n_bouncy_value = itemgroup_get(f.groups, "bouncy");
+                       // Negative bouncy may have a meaning, but we need +value here.
+                       int n_bouncy_value = abs(itemgroup_get(f.groups, "bouncy"));
 
                        int neighbors = 0;
                        if (f.drawtype == NDT_NODEBOX &&
index 5e116464213765b6546e7be4e691f1066ae077e8..50e1184283368e1f32c2e173cfa96ec06ee5a038 100644 (file)
 
 #if defined USE_CMAKE_CONFIG_H
        #include "cmake_config.h"
-#elif defined (__ANDROID__)
-       #define PROJECT_NAME "minetest"
-       #define PROJECT_NAME_C "Minetest"
-       #define STATIC_SHAREDIR ""
-       #define VERSION_STRING STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_PATCH) STR(VERSION_EXTRA)
-#ifdef NDEBUG
-               #define BUILD_TYPE "Release"
-       #else
-               #define BUILD_TYPE "Debug"
-       #endif
 #else
+       #if defined (__ANDROID__)
+               #define PROJECT_NAME "minetest"
+               #define PROJECT_NAME_C "Minetest"
+               #define STATIC_SHAREDIR ""
+               #define VERSION_STRING STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_PATCH) STR(VERSION_EXTRA)
+       #endif
        #ifdef NDEBUG
                #define BUILD_TYPE "Release"
        #else
index 3cc3af09456abfb9e8c5610118d64b247e5f5281..b9d4f8d70f2dae1d55ad46a7db291336755cf7ff 100644 (file)
@@ -64,7 +64,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 // I really don't want to make every algorithm to check if it's going near
 // the limit or not, so this is lower.
 // This is the maximum value the setting map_generation_limit can be
-#define MAX_MAP_GENERATION_LIMIT (31000)
+#define MAX_MAP_GENERATION_LIMIT (31007)
 
 // Size of node in floating-point units
 // The original idea behind this is to disallow plain casts between
@@ -111,4 +111,3 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #define TTF_DEFAULT_FONT_SIZE (16)
-#define DEFAULT_FONT_SIZE (10)
index 6f088a5b35cf011740c9946fd3bdca3ab70e4506..f75119bbbb1e3d400c13d95da0d1003eadc56171 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <json/json.h>
 #include <algorithm>
 #include "content/mods.h"
+#include "database/database.h"
 #include "filesys.h"
 #include "log.h"
 #include "content/subgames.h"
@@ -88,7 +89,7 @@ void parseModContents(ModSpec &spec)
                        modpack2_is.close();
 
                spec.is_modpack = true;
-               spec.modpack_content = getModsInPath(spec.path, true);
+               spec.modpack_content = getModsInPath(spec.path, spec.virtual_path, true);
 
        } else {
                Settings info;
@@ -166,13 +167,14 @@ void parseModContents(ModSpec &spec)
 }
 
 std::map<std::string, ModSpec> getModsInPath(
-               const std::string &path, bool part_of_modpack)
+               const std::string &path, const std::string &virtual_path, bool part_of_modpack)
 {
        // NOTE: this function works in mutual recursion with parseModContents
 
        std::map<std::string, ModSpec> result;
        std::vector<fs::DirListNode> dirlist = fs::GetDirListing(path);
-       std::string modpath;
+       std::string mod_path;
+       std::string mod_virtual_path;
 
        for (const fs::DirListNode &dln : dirlist) {
                if (!dln.dir)
@@ -184,10 +186,14 @@ std::map<std::string, ModSpec> getModsInPath(
                if (modname[0] == '.')
                        continue;
 
-               modpath.clear();
-               modpath.append(path).append(DIR_DELIM).append(modname);
+               mod_path.clear();
+               mod_path.append(path).append(DIR_DELIM).append(modname);
 
-               ModSpec spec(modname, modpath, part_of_modpack);
+               mod_virtual_path.clear();
+               // Intentionally uses / to keep paths same on different platforms
+               mod_virtual_path.append(virtual_path).append("/").append(modname);
+
+               ModSpec spec(modname, mod_path, part_of_modpack, mod_virtual_path);
                parseModContents(spec);
                result.insert(std::make_pair(modname, spec));
        }
@@ -227,9 +233,9 @@ void ModConfiguration::printUnsatisfiedModsError() const
        }
 }
 
-void ModConfiguration::addModsInPath(const std::string &path)
+void ModConfiguration::addModsInPath(const std::string &path, const std::string &virtual_path)
 {
-       addMods(flattenMods(getModsInPath(path)));
+       addMods(flattenMods(getModsInPath(path, virtual_path)));
 }
 
 void ModConfiguration::addMods(const std::vector<ModSpec> &new_mods)
@@ -293,29 +299,39 @@ void ModConfiguration::addMods(const std::vector<ModSpec> &new_mods)
 }
 
 void ModConfiguration::addModsFromConfig(
-               const std::string &settings_path, const std::set<std::string> &mods)
+               const std::string &settings_path,
+               const std::unordered_map<std::string, std::string> &modPaths)
 {
        Settings conf;
-       std::set<std::string> load_mod_names;
+       std::unordered_map<std::string, std::string> load_mod_names;
 
        conf.readConfigFile(settings_path.c_str());
        std::vector<std::string> names = conf.getNames();
        for (const std::string &name : names) {
-               if (name.compare(0, 9, "load_mod_") == 0 && conf.get(name) != "false" &&
-                               conf.get(name) != "nil")
-                       load_mod_names.insert(name.substr(9));
+               const auto &value = conf.get(name);
+               if (name.compare(0, 9, "load_mod_") == 0 && value != "false" &&
+                               value != "nil")
+                       load_mod_names[name.substr(9)] = value;
        }
 
        std::vector<ModSpec> addon_mods;
-       for (const std::string &i : mods) {
-               std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(i));
+       std::unordered_map<std::string, std::vector<std::string>> candidates;
+
+       for (const auto &modPath : modPaths) {
+               std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(modPath.second, modPath.first));
                for (std::vector<ModSpec>::const_iterator it = addon_mods_in_path.begin();
                                it != addon_mods_in_path.end(); ++it) {
                        const ModSpec &mod = *it;
-                       if (load_mod_names.count(mod.name) != 0)
-                               addon_mods.push_back(mod);
-                       else
+                       const auto &pair = load_mod_names.find(mod.name);
+                       if (pair != load_mod_names.end()) {
+                               if (is_yes(pair->second) || pair->second == mod.virtual_path) {
+                                       addon_mods.push_back(mod);
+                               } else {
+                                       candidates[pair->first].emplace_back(mod.virtual_path);
+                               }
+                       } else {
                                conf.setBool("load_mod_" + mod.name, false);
+                       }
                }
        }
        conf.updateConfigFile(settings_path.c_str());
@@ -334,9 +350,22 @@ void ModConfiguration::addModsFromConfig(
 
        if (!load_mod_names.empty()) {
                errorstream << "The following mods could not be found:";
-               for (const std::string &mod : load_mod_names)
-                       errorstream << " \"" << mod << "\"";
+               for (const auto &pair : load_mod_names)
+                       errorstream << " \"" << pair.first << "\"";
                errorstream << std::endl;
+
+               for (const auto &pair : load_mod_names) {
+                       const auto &candidate = candidates.find(pair.first);
+                       if (candidate != candidates.end()) {
+                               errorstream << "Unable to load " << pair.first << " as the specified path "
+                                       << pair.second << " could not be found. "
+                                       << "However, it is available in the following locations:"
+                                       << std::endl;
+                               for (const auto &path : candidate->second) {
+                                       errorstream << " - " << path << std::endl;
+                               }
+                       }
+               }
        }
 }
 
@@ -412,93 +441,41 @@ void ModConfiguration::resolveDependencies()
 ClientModConfiguration::ClientModConfiguration(const std::string &path) :
                ModConfiguration(path)
 {
-       std::set<std::string> paths;
+       std::unordered_map<std::string, std::string> paths;
        std::string path_user = porting::path_user + DIR_DELIM + "clientmods";
-       paths.insert(path);
-       paths.insert(path_user);
+       if (path != path_user) {
+               paths["share"] = path;
+       }
+       paths["mods"] = path_user;
 
        std::string settings_path = path_user + DIR_DELIM + "mods.conf";
        addModsFromConfig(settings_path, paths);
 }
 #endif
 
-ModMetadata::ModMetadata(const std::string &mod_name) : m_mod_name(mod_name)
+ModMetadata::ModMetadata(const std::string &mod_name, ModMetadataDatabase *database):
+       m_mod_name(mod_name), m_database(database)
 {
+       m_database->getModEntries(m_mod_name, &m_stringvars);
 }
 
 void ModMetadata::clear()
 {
+       for (const auto &pair : m_stringvars) {
+               m_database->removeModEntry(m_mod_name, pair.first);
+       }
        Metadata::clear();
-       m_modified = true;
 }
 
-bool ModMetadata::save(const std::string &root_path)
+bool ModMetadata::setString(const std::string &name, const std::string &var)
 {
-       Json::Value json;
-       for (StringMap::const_iterator it = m_stringvars.begin();
-                       it != m_stringvars.end(); ++it) {
-               json[it->first] = it->second;
-       }
-
-       if (!fs::PathExists(root_path)) {
-               if (!fs::CreateAllDirs(root_path)) {
-                       errorstream << "ModMetadata[" << m_mod_name
-                                   << "]: Unable to save. '" << root_path
-                                   << "' tree cannot be created." << std::endl;
-                       return false;
+       if (Metadata::setString(name, var)) {
+               if (var.empty()) {
+                       m_database->removeModEntry(m_mod_name, name);
+               } else {
+                       m_database->setModEntry(m_mod_name, name, var);
                }
-       } else if (!fs::IsDir(root_path)) {
-               errorstream << "ModMetadata[" << m_mod_name << "]: Unable to save. '"
-                           << root_path << "' is not a directory." << std::endl;
-               return false;
-       }
-
-       bool w_ok = fs::safeWriteToFile(
-                       root_path + DIR_DELIM + m_mod_name, fastWriteJson(json));
-
-       if (w_ok) {
-               m_modified = false;
-       } else {
-               errorstream << "ModMetadata[" << m_mod_name << "]: failed write file."
-                           << std::endl;
-       }
-       return w_ok;
-}
-
-bool ModMetadata::load(const std::string &root_path)
-{
-       m_stringvars.clear();
-
-       std::ifstream is((root_path + DIR_DELIM + m_mod_name).c_str(),
-                       std::ios_base::binary);
-       if (!is.good()) {
-               return false;
-       }
-
-       Json::Value root;
-       Json::CharReaderBuilder builder;
-       builder.settings_["collectComments"] = false;
-       std::string errs;
-
-       if (!Json::parseFromStream(builder, is, &root, &errs)) {
-               errorstream << "ModMetadata[" << m_mod_name
-                           << "]: failed read data "
-                              "(Json decoding failure). Message: "
-                           << errs << std::endl;
-               return false;
-       }
-
-       const Json::Value::Members attr_list = root.getMemberNames();
-       for (const auto &it : attr_list) {
-               Json::Value attr_value = root[it];
-               m_stringvars[it] = attr_value.asString();
+               return true;
        }
-
-       return true;
-}
-
-bool ModMetadata::setString(const std::string &name, const std::string &var)
-{
-       m_modified = Metadata::setString(name, var);
-       return m_modified;
+       return false;
 }
index b56a97edbb910fc1122bd0ccbc4d5ac1b620ebd0..ab0a9300e89b8aee0e66d90a4a5173b416d3d849 100644 (file)
@@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "config.h"
 #include "metadata.h"
 
+class ModMetadataDatabase;
+
 #define MODNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_"
 
 struct ModSpec
@@ -49,17 +51,36 @@ struct ModSpec
        bool part_of_modpack = false;
        bool is_modpack = false;
 
+       /**
+        * A constructed canonical path to represent this mod's location.
+        * This intended to be used as an identifier for a modpath that tolerates file movement,
+        * and cannot be used to read the mod files.
+        *
+        * Note that `mymod` is the directory name, not the mod name specified in mod.conf.
+        *
+        * Ex:
+        *
+        * - mods/mymod
+        * - mods/mymod (1)
+        *     (^ this would have name=mymod in mod.conf)
+        * - mods/modpack1/mymod
+        * - games/mygame/mods/mymod
+        * - worldmods/mymod
+        */
+       std::string virtual_path;
+
        // For logging purposes
        std::vector<const char *> deprecation_msgs;
 
        // if modpack:
        std::map<std::string, ModSpec> modpack_content;
-       ModSpec(const std::string &name = "", const std::string &path = "") :
-                       name(name), path(path)
+
+       ModSpec()
        {
        }
-       ModSpec(const std::string &name, const std::string &path, bool part_of_modpack) :
-                       name(name), path(path), part_of_modpack(part_of_modpack)
+
+       ModSpec(const std::string &name, const std::string &path, bool part_of_modpack, const std::string &virtual_path) :
+                       name(name), path(path), part_of_modpack(part_of_modpack), virtual_path(virtual_path)
        {
        }
 
@@ -69,8 +90,16 @@ struct ModSpec
 // Retrieves depends, optdepends, is_modpack and modpack_content
 void parseModContents(ModSpec &mod);
 
-std::map<std::string, ModSpec> getModsInPath(
-               const std::string &path, bool part_of_modpack = false);
+/**
+ * Gets a list of all mods and modpacks in path
+ *
+ * @param Path to search, should be absolute
+ * @param part_of_modpack Is this searching within a modpack?
+ * @param virtual_path Virtual path for this directory, see comment in ModSpec
+ * @returns map of mods
+ */
+std::map<std::string, ModSpec> getModsInPath(const std::string &path,
+               const std::string &virtual_path, bool part_of_modpack = false);
 
 // replaces modpack Modspecs with their content
 std::vector<ModSpec> flattenMods(const std::map<std::string, ModSpec> &mods);
@@ -95,15 +124,25 @@ class ModConfiguration
 
 protected:
        ModConfiguration(const std::string &worldpath);
-       // adds all mods in the given path. used for games, modpacks
-       // and world-specific mods (worldmods-folders)
-       void addModsInPath(const std::string &path);
+
+       /**
+        * adds all mods in the given path. used for games, modpacks
+        * and world-specific mods (worldmods-folders)
+        *
+        * @param path To search, should be absolute
+        * @param virtual_path Virtual path for this directory, see comment in ModSpec
+        */
+       void addModsInPath(const std::string &path, const std::string &virtual_path);
 
        // adds all mods in the set.
        void addMods(const std::vector<ModSpec> &new_mods);
 
+       /**
+        * @param settings_path Path to world.mt
+        * @param modPaths Map from virtual name to mod path
+        */
        void addModsFromConfig(const std::string &settings_path,
-                       const std::set<std::string> &mods);
+                       const std::unordered_map<std::string, std::string> &modPaths);
 
        void checkConflictsAndDeps();
 
@@ -149,20 +188,16 @@ class ModMetadata : public Metadata
 {
 public:
        ModMetadata() = delete;
-       ModMetadata(const std::string &mod_name);
+       ModMetadata(const std::string &mod_name, ModMetadataDatabase *database);
        ~ModMetadata() = default;
 
        virtual void clear();
 
-       bool save(const std::string &root_path);
-       bool load(const std::string &root_path);
-
-       bool isModified() const { return m_modified; }
        const std::string &getModName() const { return m_mod_name; }
 
        virtual bool setString(const std::string &name, const std::string &var);
 
 private:
        std::string m_mod_name;
-       bool m_modified = false;
+       ModMetadataDatabase *m_database;
 };
index e9dc609b0a231b467de0b571874a7ee52425400f..23355990ec442671acd4e7fe8bf73853cd63645a 100644 (file)
@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "util/strfnd.h"
 #include "defaultsettings.h" // for set_default_settings
-#include "mapgen/mapgen.h"   // for MapgenParams
+#include "map_settings_manager.h"
 #include "util/string.h"
 
 #ifndef SERVER
@@ -107,11 +107,14 @@ SubgameSpec findSubgame(const std::string &id)
        std::string gamemod_path = game_path + DIR_DELIM + "mods";
 
        // Find mod directories
-       std::set<std::string> mods_paths;
-       if (!user_game)
-               mods_paths.insert(share + DIR_DELIM + "mods");
-       if (user != share || user_game)
-               mods_paths.insert(user + DIR_DELIM + "mods");
+       std::unordered_map<std::string, std::string> mods_paths;
+       mods_paths["mods"] = user + DIR_DELIM + "mods";
+       if (!user_game && user != share)
+               mods_paths["share"] = share + DIR_DELIM + "mods";
+
+       for (const std::string &mod_path : getEnvModPaths()) {
+               mods_paths[fs::AbsolutePath(mod_path)] = mod_path;
+       }
 
        // Get meta
        std::string conf_path = game_path + DIR_DELIM + "game.conf";
@@ -354,6 +357,7 @@ void loadGameConfAndInitWorld(const std::string &path, const std::string &name,
                conf.set("backend", "sqlite3");
                conf.set("player_backend", "sqlite3");
                conf.set("auth_backend", "sqlite3");
+               conf.set("mod_storage_backend", "sqlite3");
                conf.setBool("creative_mode", g_settings->getBool("creative_mode"));
                conf.setBool("enable_damage", g_settings->getBool("enable_damage"));
 
@@ -365,22 +369,25 @@ void loadGameConfAndInitWorld(const std::string &path, const std::string &name,
        // Create map_meta.txt if does not already exist
        std::string map_meta_path = final_path + DIR_DELIM + "map_meta.txt";
        if (!fs::PathExists(map_meta_path)) {
-               verbosestream << "Creating map_meta.txt (" << map_meta_path << ")"
-                             << std::endl;
-               std::ostringstream oss(std::ios_base::binary);
-
-               Settings conf;
-               MapgenParams params;
+               MapSettingsManager mgr(map_meta_path);
 
-               params.readParams(g_settings);
-               params.writeParams(&conf);
-               conf.writeLines(oss);
-               oss << "[end_of_params]\n";
+               mgr.setMapSetting("seed", g_settings->get("fixed_map_seed"));
 
-               fs::safeWriteToFile(map_meta_path, oss.str());
+               mgr.makeMapgenParams();
+               mgr.saveMapMeta();
        }
 
        // The Settings object is no longer needed for created worlds
        if (new_game_settings)
                delete game_settings;
 }
+
+std::vector<std::string> getEnvModPaths()
+{
+       const char *c_mod_path = getenv("MINETEST_MOD_PATH");
+       std::vector<std::string> paths;
+       Strfnd search_paths(c_mod_path ? c_mod_path : "");
+       while (!search_paths.at_end())
+               paths.push_back(search_paths.next(PATH_DELIM));
+       return paths;
+}
index 60392639b51d823bcc56fd5473822041a7806256..d36b4952fde076fd490ed6dbb17ce4f066efea30 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <string>
 #include <set>
+#include <unordered_map>
 #include <vector>
 
 class Settings;
@@ -33,13 +34,16 @@ struct SubgameSpec
        int release;
        std::string path;
        std::string gamemods_path;
-       std::set<std::string> addon_mods_paths;
+
+       /**
+        * Map from virtual path to mods path
+        */
+       std::unordered_map<std::string, std::string> addon_mods_paths;
        std::string menuicon_path;
 
        SubgameSpec(const std::string &id = "", const std::string &path = "",
                        const std::string &gamemods_path = "",
-                       const std::set<std::string> &addon_mods_paths =
-                                       std::set<std::string>(),
+                       const std::unordered_map<std::string, std::string> &addon_mods_paths = {},
                        const std::string &name = "",
                        const std::string &menuicon_path = "",
                        const std::string &author = "", int release = 0) :
@@ -58,6 +62,8 @@ SubgameSpec findWorldSubgame(const std::string &world_path);
 
 std::set<std::string> getAvailableGameIds();
 std::vector<SubgameSpec> getAvailableGames();
+// Get the list of paths to mods in the environment variable $MINETEST_MOD_PATH
+std::vector<std::string> getEnvModPaths();
 
 bool getWorldExists(const std::string &world_path);
 //! Try to get the displayed name of a world
index 21060519839072636a897a13efb31c58645c535b..c05a0cfb75c57984121425015e35c0ffdf7d0563 100644 (file)
@@ -734,7 +734,8 @@ bool CraftDefinitionCooking::check(const CraftInput &input, IGameDef *gamedef) c
        }
 
        // Check the single input item
-       return inputItemMatchesRecipe(input_filtered[0], recipe, gamedef->idef());
+       std::string rec_name = craftGetItemName(recipe, gamedef);
+       return inputItemMatchesRecipe(input_filtered[0], rec_name, gamedef->idef());
 }
 
 CraftOutput CraftDefinitionCooking::getOutput(const CraftInput &input, IGameDef *gamedef) const
@@ -836,7 +837,8 @@ bool CraftDefinitionFuel::check(const CraftInput &input, IGameDef *gamedef) cons
        }
 
        // Check the single input item
-       return inputItemMatchesRecipe(input_filtered[0], recipe, gamedef->idef());
+       std::string rec_name = craftGetItemName(recipe, gamedef);
+       return inputItemMatchesRecipe(input_filtered[0], rec_name, gamedef->idef());
 }
 
 CraftOutput CraftDefinitionFuel::getOutput(const CraftInput &input, IGameDef *gamedef) const
index b56f341c5bbc63636739594da59dff2a287fa60f..629b2fb0492261cf30d71f59652a8c17318a8a5e 100644 (file)
@@ -80,3 +80,41 @@ void Database_Dummy::listPlayers(std::vector<std::string> &res)
                res.emplace_back(player);
        }
 }
+
+bool Database_Dummy::getModEntries(const std::string &modname, StringMap *storage)
+{
+       const auto mod_pair = m_mod_meta_database.find(modname);
+       if (mod_pair != m_mod_meta_database.cend()) {
+               for (const auto &pair : mod_pair->second) {
+                       (*storage)[pair.first] = pair.second;
+               }
+       }
+       return true;
+}
+
+bool Database_Dummy::setModEntry(const std::string &modname,
+       const std::string &key, const std::string &value)
+{
+       auto mod_pair = m_mod_meta_database.find(modname);
+       if (mod_pair == m_mod_meta_database.end()) {
+               m_mod_meta_database[modname] = StringMap({{key, value}});
+       } else {
+               mod_pair->second[key] = value;
+       }
+       return true;
+}
+
+bool Database_Dummy::removeModEntry(const std::string &modname, const std::string &key)
+{
+       auto mod_pair = m_mod_meta_database.find(modname);
+       if (mod_pair != m_mod_meta_database.end())
+               return mod_pair->second.erase(key) > 0;
+       return false;
+}
+
+void Database_Dummy::listMods(std::vector<std::string> *res)
+{
+       for (const auto &pair : m_mod_meta_database) {
+               res->push_back(pair.first);
+       }
+}
index b69919f84512e9fcdd38e1592e25e7c58e38daf0..44b9e8d6847d637c74b68e988d0deb20870dbcef 100644 (file)
@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "database.h"
 #include "irrlichttypes.h"
 
-class Database_Dummy : public MapDatabase, public PlayerDatabase
+class Database_Dummy : public MapDatabase, public PlayerDatabase, public ModMetadataDatabase
 {
 public:
        bool saveBlock(const v3s16 &pos, const std::string &data);
@@ -37,10 +37,17 @@ class Database_Dummy : public MapDatabase, public PlayerDatabase
        bool removePlayer(const std::string &name);
        void listPlayers(std::vector<std::string> &res);
 
+       bool getModEntries(const std::string &modname, StringMap *storage);
+       bool setModEntry(const std::string &modname,
+                       const std::string &key, const std::string &value);
+       bool removeModEntry(const std::string &modname, const std::string &key);
+       void listMods(std::vector<std::string> *res);
+
        void beginSave() {}
        void endSave() {}
 
 private:
        std::map<s64, std::string> m_database;
        std::set<std::string> m_player_database;
+       std::unordered_map<std::string, StringMap> m_mod_meta_database;
 };
index d9d113b4e8b0ad0addfe2a7a410cf7d696bb2cb0..7c0dbac28c3a1dce7f6ad59009e092c4c3d54736 100644 (file)
@@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include <cassert>
-#include <json/json.h>
 #include "convert_json.h"
 #include "database-files.h"
 #include "remoteplayer.h"
@@ -376,3 +375,127 @@ bool AuthDatabaseFiles::writeAuthFile()
        }
        return true;
 }
+
+ModMetadataDatabaseFiles::ModMetadataDatabaseFiles(const std::string &savedir):
+       m_storage_dir(savedir + DIR_DELIM + "mod_storage")
+{
+}
+
+bool ModMetadataDatabaseFiles::getModEntries(const std::string &modname, StringMap *storage)
+{
+       Json::Value *meta = getOrCreateJson(modname);
+       if (!meta)
+               return false;
+
+       const Json::Value::Members attr_list = meta->getMemberNames();
+       for (const auto &it : attr_list) {
+               Json::Value attr_value = (*meta)[it];
+               (*storage)[it] = attr_value.asString();
+       }
+
+       return true;
+}
+
+bool ModMetadataDatabaseFiles::setModEntry(const std::string &modname,
+       const std::string &key, const std::string &value)
+{
+       Json::Value *meta = getOrCreateJson(modname);
+       if (!meta)
+               return false;
+
+       (*meta)[key] = Json::Value(value);
+       m_modified.insert(modname);
+
+       return true;
+}
+
+bool ModMetadataDatabaseFiles::removeModEntry(const std::string &modname,
+               const std::string &key)
+{
+       Json::Value *meta = getOrCreateJson(modname);
+       if (!meta)
+               return false;
+
+       Json::Value removed;
+       if (meta->removeMember(key, &removed)) {
+               m_modified.insert(modname);
+               return true;
+       }
+       return false;
+}
+
+void ModMetadataDatabaseFiles::beginSave()
+{
+}
+
+void ModMetadataDatabaseFiles::endSave()
+{
+       if (m_modified.empty())
+               return;
+
+       if (!fs::CreateAllDirs(m_storage_dir)) {
+               errorstream << "ModMetadataDatabaseFiles: Unable to save. '"
+                               << m_storage_dir << "' cannot be created." << std::endl;
+               return;
+       }
+       if (!fs::IsDir(m_storage_dir)) {
+               errorstream << "ModMetadataDatabaseFiles: Unable to save. '"
+                               << m_storage_dir << "' is not a directory." << std::endl;
+               return;
+       }
+
+       for (auto it = m_modified.begin(); it != m_modified.end();) {
+               const std::string &modname = *it;
+
+               const Json::Value &json = m_mod_meta[modname];
+
+               if (!fs::safeWriteToFile(m_storage_dir + DIR_DELIM + modname, fastWriteJson(json))) {
+                       errorstream << "ModMetadataDatabaseFiles[" << modname
+                                       << "]: failed to write file." << std::endl;
+                       ++it;
+                       continue;
+               }
+
+               it = m_modified.erase(it);
+       }
+}
+
+void ModMetadataDatabaseFiles::listMods(std::vector<std::string> *res)
+{
+       // List in-memory metadata first.
+       for (const auto &pair : m_mod_meta) {
+               res->push_back(pair.first);
+       }
+
+       // List other metadata present in the filesystem.
+       for (const auto &entry : fs::GetDirListing(m_storage_dir)) {
+               if (!entry.dir && m_mod_meta.count(entry.name) == 0)
+                       res->push_back(entry.name);
+       }
+}
+
+Json::Value *ModMetadataDatabaseFiles::getOrCreateJson(const std::string &modname)
+{
+       auto found = m_mod_meta.find(modname);
+       if (found != m_mod_meta.end())
+               return &found->second;
+
+       Json::Value meta(Json::objectValue);
+
+       std::string path = m_storage_dir + DIR_DELIM + modname;
+       if (fs::PathExists(path)) {
+               std::ifstream is(path.c_str(), std::ios_base::binary);
+
+               Json::CharReaderBuilder builder;
+               builder.settings_["collectComments"] = false;
+               std::string errs;
+
+               if (!Json::parseFromStream(builder, is, &meta, &errs)) {
+                       errorstream << "ModMetadataDatabaseFiles[" << modname
+                                       << "]: failed to decode data: " << errs << std::endl;
+                       return nullptr;
+               }
+       }
+
+       return &(m_mod_meta[modname] = meta);
+}
index e647a2e242219f770f0836a09165956722f3a21f..962e4d7bb376960eccdb5cc7a9f64c626916206d 100644 (file)
@@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "database.h"
 #include <unordered_map>
+#include <unordered_set>
+#include <json/json.h>
 
 class PlayerDatabaseFiles : public PlayerDatabase
 {
@@ -69,3 +71,27 @@ class AuthDatabaseFiles : public AuthDatabase
        bool readAuthFile();
        bool writeAuthFile();
 };
+
+class ModMetadataDatabaseFiles : public ModMetadataDatabase
+{
+public:
+       ModMetadataDatabaseFiles(const std::string &savedir);
+       virtual ~ModMetadataDatabaseFiles() = default;
+
+       virtual bool getModEntries(const std::string &modname, StringMap *storage);
+       virtual bool setModEntry(const std::string &modname,
+               const std::string &key, const std::string &value);
+       virtual bool removeModEntry(const std::string &modname, const std::string &key);
+       virtual void listMods(std::vector<std::string> *res);
+
+       virtual void beginSave();
+       virtual void endSave();
+
+private:
+       Json::Value *getOrCreateJson(const std::string &modname);
+       bool writeJson(const std::string &modname, const Json::Value &json);
+
+       std::string m_storage_dir;
+       std::unordered_map<std::string, Json::Value> m_mod_meta;
+       std::unordered_set<std::string> m_modified;
+};
index 39f4c84423030fa7e9b0cfb0dbe35cd4e8bcea1b..6e59daab3c9ba60bcbe93fa35c5a40831be01f90 100644 (file)
@@ -74,7 +74,7 @@ void Database_LevelDB::loadBlock(const v3s16 &pos, std::string *block)
                i64tos(getBlockAsInteger(pos)), block);
 
        if (!status.ok())
-               block->clear(); 
+               block->clear();
 }
 
 bool Database_LevelDB::deleteBlock(const v3s16 &pos)
index 3469f424286873609379d77d621ccdb1b560d1d8..9d6501e68d66a9fac29017995ea053f7ba182afd 100644 (file)
@@ -495,7 +495,7 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player)
        execPrepared("remove_player_inventories", 1, rmvalues);
        execPrepared("remove_player_inventory_items", 1, rmvalues);
 
-       std::vector<const InventoryList*> inventory_lists = sao->getInventory()->getLists();
+       const auto &inventory_lists = sao->getInventory()->getLists();
        std::ostringstream oss;
        for (u16 i = 0; i < inventory_lists.size(); i++) {
                const InventoryList* list = inventory_lists[i];
index 81b4a2b10ac483055cee00e5528bd46d53f0dbe6..0a9ead01ea2d0c34461be59cf79fab128b1daf24 100644 (file)
@@ -94,7 +94,8 @@ class Database_PostgreSQL: public Database
                checkResults(PQprepare(m_conn, name.c_str(), sql.c_str(), 0, NULL));
        }
 
-       const int getPGVersion() const { return m_pgversion; }
+       int getPGVersion() const { return m_pgversion; }
+
 private:
        // Database connectivity checks
        void ping();
index 898acc265da02c0028bfd4be1d9eb712ad384855..9521085e93a5352f2db38d976233c54292235bb7 100644 (file)
@@ -228,11 +228,7 @@ void MapDatabaseSQLite3::createDatabase()
 void MapDatabaseSQLite3::initStatements()
 {
        PREPARE_STATEMENT(read, "SELECT `data` FROM `blocks` WHERE `pos` = ? LIMIT 1");
-#ifdef __ANDROID__
-       PREPARE_STATEMENT(write,  "INSERT INTO `blocks` (`pos`, `data`) VALUES (?, ?)");
-#else
        PREPARE_STATEMENT(write, "REPLACE INTO `blocks` (`pos`, `data`) VALUES (?, ?)");
-#endif
        PREPARE_STATEMENT(delete, "DELETE FROM `blocks` WHERE `pos` = ?");
        PREPARE_STATEMENT(list, "SELECT `pos` FROM `blocks`");
 
@@ -265,19 +261,6 @@ bool MapDatabaseSQLite3::saveBlock(const v3s16 &pos, const std::string &data)
 {
        verifyDatabase();
 
-#ifdef __ANDROID__
-       /**
-        * Note: For some unknown reason SQLite3 fails to REPLACE blocks on Android,
-        * deleting them and then inserting works.
-        */
-       bindPos(m_stmt_read, pos);
-
-       if (sqlite3_step(m_stmt_read) == SQLITE_ROW) {
-               deleteBlock(pos);
-       }
-       sqlite3_reset(m_stmt_read);
-#endif
-
        bindPos(m_stmt_write, pos);
        SQLOK(sqlite3_bind_blob(m_stmt_write, 2, data.data(), data.size(), NULL),
                "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
@@ -493,10 +476,10 @@ void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player)
        sqlite3_vrfy(sqlite3_step(m_stmt_player_remove_inventory_items), SQLITE_DONE);
        sqlite3_reset(m_stmt_player_remove_inventory_items);
 
-       std::vector<const InventoryList*> inventory_lists = sao->getInventory()->getLists();
+       const auto &inventory_lists = sao->getInventory()->getLists();
        std::ostringstream oss;
        for (u16 i = 0; i < inventory_lists.size(); i++) {
-               const InventoryListlist = inventory_lists[i];
+               const InventoryList *list = inventory_lists[i];
 
                str_to_sqlite(m_stmt_player_add_inventory, 1, player->getName());
                int_to_sqlite(m_stmt_player_add_inventory, 2, i);
@@ -779,3 +762,108 @@ void AuthDatabaseSQLite3::writePrivileges(const AuthEntry &authEntry)
                sqlite3_reset(m_stmt_write_privs);
        }
 }
+
+ModMetadataDatabaseSQLite3::ModMetadataDatabaseSQLite3(const std::string &savedir):
+       Database_SQLite3(savedir, "mod_storage"), ModMetadataDatabase()
+{
+}
+
+ModMetadataDatabaseSQLite3::~ModMetadataDatabaseSQLite3()
+{
+       FINALIZE_STATEMENT(m_stmt_remove)
+       FINALIZE_STATEMENT(m_stmt_set)
+       FINALIZE_STATEMENT(m_stmt_get)
+}
+
+void ModMetadataDatabaseSQLite3::createDatabase()
+{
+       assert(m_database); // Pre-condition
+
+       SQLOK(sqlite3_exec(m_database,
+               "CREATE TABLE IF NOT EXISTS `entries` (\n"
+                       "       `modname` TEXT NOT NULL,\n"
+                       "       `key` BLOB NOT NULL,\n"
+                       "       `value` BLOB NOT NULL,\n"
+                       "       PRIMARY KEY (`modname`, `key`)\n"
+                       ");\n",
+               NULL, NULL, NULL),
+               "Failed to create database table");
+}
+
+void ModMetadataDatabaseSQLite3::initStatements()
+{
+       PREPARE_STATEMENT(get, "SELECT `key`, `value` FROM `entries` WHERE `modname` = ?");
+       PREPARE_STATEMENT(set,
+               "REPLACE INTO `entries` (`modname`, `key`, `value`) VALUES (?, ?, ?)");
+       PREPARE_STATEMENT(remove, "DELETE FROM `entries` WHERE `modname` = ? AND `key` = ?");
+}
+
+bool ModMetadataDatabaseSQLite3::getModEntries(const std::string &modname, StringMap *storage)
+{
+       verifyDatabase();
+
+       str_to_sqlite(m_stmt_get, 1, modname);
+       while (sqlite3_step(m_stmt_get) == SQLITE_ROW) {
+               const char *key_data = (const char *) sqlite3_column_blob(m_stmt_get, 0);
+               size_t key_len = sqlite3_column_bytes(m_stmt_get, 0);
+               const char *value_data = (const char *) sqlite3_column_blob(m_stmt_get, 1);
+               size_t value_len = sqlite3_column_bytes(m_stmt_get, 1);
+               (*storage)[std::string(key_data, key_len)] = std::string(value_data, value_len);
+       }
+       sqlite3_vrfy(sqlite3_errcode(m_database), SQLITE_DONE);
+
+       sqlite3_reset(m_stmt_get);
+
+       return true;
+}
+
+bool ModMetadataDatabaseSQLite3::setModEntry(const std::string &modname,
+       const std::string &key, const std::string &value)
+{
+       verifyDatabase();
+
+       str_to_sqlite(m_stmt_set, 1, modname);
+       SQLOK(sqlite3_bind_blob(m_stmt_set, 2, key.data(), key.size(), NULL),
+               "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
+       SQLOK(sqlite3_bind_blob(m_stmt_set, 3, value.data(), value.size(), NULL),
+               "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
+       SQLRES(sqlite3_step(m_stmt_set), SQLITE_DONE, "Failed to set mod entry")
+
+       sqlite3_reset(m_stmt_set);
+
+       return true;
+}
+
+bool ModMetadataDatabaseSQLite3::removeModEntry(const std::string &modname,
+               const std::string &key)
+{
+       verifyDatabase();
+
+       str_to_sqlite(m_stmt_remove, 1, modname);
+       SQLOK(sqlite3_bind_blob(m_stmt_remove, 2, key.data(), key.size(), NULL),
+               "Internal error: failed to bind query at " __FILE__ ":" TOSTRING(__LINE__));
+       sqlite3_vrfy(sqlite3_step(m_stmt_remove), SQLITE_DONE);
+       int changes = sqlite3_changes(m_database);
+
+       sqlite3_reset(m_stmt_remove);
+
+       return changes > 0;
+}
+
+void ModMetadataDatabaseSQLite3::listMods(std::vector<std::string> *res)
+{
+       verifyDatabase();
+
+       char *errmsg;
+       int status = sqlite3_exec(m_database,
+               "SELECT `modname` FROM `entries` GROUP BY `modname`;",
+               [](void *res_vp, int n_col, char **cols, char **col_names) -> int {
+                       ((decltype(res)) res_vp)->emplace_back(cols[0]);
+                       return 0;
+               }, (void *) res, &errmsg);
+       if (status != SQLITE_OK) {
+               DatabaseException e(std::string("Error trying to list mods with metadata: ") + errmsg);
+               sqlite3_free(errmsg);
+               throw e;
+       }
+}
index d7202a91864063b06c9424e1e6fe9b88cb32615b..5e3d7c96c662159649cda95f0ccafcf0bb970f8c 100644 (file)
@@ -232,3 +232,28 @@ class AuthDatabaseSQLite3 : private Database_SQLite3, public AuthDatabase
        sqlite3_stmt *m_stmt_delete_privs = nullptr;
        sqlite3_stmt *m_stmt_last_insert_rowid = nullptr;
 };
+
+class ModMetadataDatabaseSQLite3 : private Database_SQLite3, public ModMetadataDatabase
+{
+public:
+       ModMetadataDatabaseSQLite3(const std::string &savedir);
+       virtual ~ModMetadataDatabaseSQLite3();
+
+       virtual bool getModEntries(const std::string &modname, StringMap *storage);
+       virtual bool setModEntry(const std::string &modname,
+               const std::string &key, const std::string &value);
+       virtual bool removeModEntry(const std::string &modname, const std::string &key);
+       virtual void listMods(std::vector<std::string> *res);
+
+       virtual void beginSave() { Database_SQLite3::beginSave(); }
+       virtual void endSave() { Database_SQLite3::endSave(); }
+
+protected:
+       virtual void createDatabase();
+       virtual void initStatements();
+
+private:
+       sqlite3_stmt *m_stmt_get = nullptr;
+       sqlite3_stmt *m_stmt_set = nullptr;
+       sqlite3_stmt *m_stmt_remove = nullptr;
+};
index b7d5519350441a8e8e37cec08e8cd65319723881..fbb5befea294e289da3e03713735acfb14a78e35 100644 (file)
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irr_v3d.h"
 #include "irrlichttypes.h"
 #include "util/basic_macros.h"
+#include "util/string.h"
 
 class Database
 {
@@ -84,3 +85,15 @@ class AuthDatabase
        virtual void listNames(std::vector<std::string> &res) = 0;
        virtual void reload() = 0;
 };
+
+class ModMetadataDatabase : public Database
+{
+public:
+       virtual ~ModMetadataDatabase() = default;
+
+       virtual bool getModEntries(const std::string &modname, StringMap *storage) = 0;
+       virtual bool setModEntry(const std::string &modname,
+               const std::string &key, const std::string &value) = 0;
+       virtual bool removeModEntry(const std::string &modname, const std::string &key) = 0;
+       virtual void listMods(std::vector<std::string> *res) = 0;
+};
index 0d509752bd61c1f4d1e40119febf9950d1528046..ef2f8724dbc9d134bd2bf4f3a9f4e1ef0acc6823 100644 (file)
@@ -65,7 +65,6 @@ void set_default_settings()
        settings->setDefault("max_out_chat_queue_size", "20");
        settings->setDefault("pause_on_lost_focus", "false");
        settings->setDefault("enable_register_confirmation", "true");
-       settings->setDefault("clickable_chat_weblinks", "false");
        settings->setDefault("chat_weblink_color", "#8888FF");
 
        // Cheat Menu
@@ -254,6 +253,7 @@ void set_default_settings()
        settings->setDefault("leaves_style", "fancy");
        settings->setDefault("connected_glass", "false");
        settings->setDefault("smooth_lighting", "true");
+       settings->setDefault("performance_tradeoffs", "false");
        settings->setDefault("lighting_alpha", "0.0");
        settings->setDefault("lighting_beta", "1.5");
        settings->setDefault("display_gamma", "1.0");
@@ -313,6 +313,7 @@ void set_default_settings()
        settings->setDefault("enable_particles", "true");
        settings->setDefault("arm_inertia", "true");
        settings->setDefault("show_nametag_backgrounds", "true");
+       settings->setDefault("transparency_sorting_distance", "16");
 
        settings->setDefault("enable_minimap", "true");
        settings->setDefault("minimap_shape_round", "false");
@@ -335,7 +336,7 @@ void set_default_settings()
 
        // Effects Shadows
        settings->setDefault("enable_dynamic_shadows", "false");
-       settings->setDefault("shadow_strength", "0.2");
+       settings->setDefault("shadow_strength_gamma", "1.0");
        settings->setDefault("shadow_map_max_distance", "200.0");
        settings->setDefault("shadow_map_texture_size", "2048");
        settings->setDefault("shadow_map_texture_32bit", "true");
@@ -355,7 +356,7 @@ void set_default_settings()
        settings->setDefault("aux1_descends", "false");
        settings->setDefault("doubletap_jump", "false");
        settings->setDefault("always_fly_fast", "true");
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        settings->setDefault("autojump", "true");
 #else
        settings->setDefault("autojump", "false");
@@ -372,8 +373,7 @@ void set_default_settings()
        settings->setDefault("main_menu_path", "");
        settings->setDefault("serverlist_file", "favoriteservers.json");
 
-#if USE_FREETYPE
-       settings->setDefault("freetype", "true");
+       // General font settings
        settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "Arimo-Regular.ttf"));
        settings->setDefault("font_path_italic", porting::getDataPath("fonts" DIR_DELIM "Arimo-Italic.ttf"));
        settings->setDefault("font_path_bold", porting::getDataPath("fonts" DIR_DELIM "Arimo-Bold.ttf"));
@@ -382,21 +382,15 @@ void set_default_settings()
        settings->setDefault("font_italic", "false");
        settings->setDefault("font_shadow", "1");
        settings->setDefault("font_shadow_alpha", "127");
+       settings->setDefault("font_size_divisible_by", "1");
        settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "Cousine-Regular.ttf"));
        settings->setDefault("mono_font_path_italic", porting::getDataPath("fonts" DIR_DELIM "Cousine-Italic.ttf"));
        settings->setDefault("mono_font_path_bold", porting::getDataPath("fonts" DIR_DELIM "Cousine-Bold.ttf"));
        settings->setDefault("mono_font_path_bold_italic", porting::getDataPath("fonts" DIR_DELIM "Cousine-BoldItalic.ttf"));
+       settings->setDefault("mono_font_size_divisible_by", "1");
        settings->setDefault("fallback_font_path", porting::getDataPath("fonts" DIR_DELIM "DroidSansFallbackFull.ttf"));
 
        std::string font_size_str = std::to_string(TTF_DEFAULT_FONT_SIZE);
-#else
-       settings->setDefault("freetype", "false");
-       settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "mono_dejavu_sans"));
-       settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "mono_dejavu_sans"));
-
-       std::string font_size_str = std::to_string(DEFAULT_FONT_SIZE);
-#endif
-       // General font settings
        settings->setDefault("font_size", font_size_str);
        settings->setDefault("mono_font_size", font_size_str);
        settings->setDefault("chat_font_size", "0"); // Default "font_size"
@@ -462,7 +456,7 @@ void set_default_settings()
        settings->setDefault("time_speed", "72");
        settings->setDefault("world_start_time", "6125");
        settings->setDefault("server_unload_unused_data_timeout", "29");
-       settings->setDefault("max_objects_per_block", "64");
+       settings->setDefault("max_objects_per_block", "256");
        settings->setDefault("server_map_save_interval", "5.3");
        settings->setDefault("chat_message_max_size", "500");
        settings->setDefault("chat_message_limit_per_10sec", "8.0");
@@ -511,7 +505,7 @@ void set_default_settings()
        // Mapgen
        settings->setDefault("mg_name", "v7");
        settings->setDefault("water_level", "1");
-       settings->setDefault("mapgen_limit", "31000");
+       settings->setDefault("mapgen_limit", "31007");
        settings->setDefault("chunksize", "5");
        settings->setDefault("fixed_map_seed", "");
        settings->setDefault("max_block_generate_distance", "10");
@@ -527,6 +521,7 @@ void set_default_settings()
 
        settings->setDefault("enable_console", "false");
        settings->setDefault("screen_dpi", "72");
+       settings->setDefault("display_density_factor", "1");
 
        // Altered settings for macOS
 #if defined(__MACH__) && defined(__APPLE__)
@@ -534,16 +529,22 @@ void set_default_settings()
        settings->setDefault("fps_max", "0");
 #endif
 
+#ifdef HAVE_TOUCHSCREENGUI
+       settings->setDefault("touchtarget", "true");
+       settings->setDefault("touchscreen_threshold","20");
+       settings->setDefault("fixed_virtual_joystick", "false");
+       settings->setDefault("virtual_joystick_triggers_aux1", "false");
+       settings->setDefault("clickable_chat_weblinks", "false");
+#else
+       settings->setDefault("clickable_chat_weblinks", "true");
+#endif
        // Altered settings for Android
 #ifdef __ANDROID__
        settings->setDefault("screen_w", "0");
        settings->setDefault("screen_h", "0");
        settings->setDefault("fullscreen", "true");
-       settings->setDefault("touchtarget", "true");
-       settings->setDefault("touchscreen_threshold","20");
-       settings->setDefault("fixed_virtual_joystick", "false");
-       settings->setDefault("virtual_joystick_triggers_aux1", "false");
        settings->setDefault("smooth_lighting", "false");
+       settings->setDefault("performance_tradeoffs", "true");
        settings->setDefault("max_simultaneous_block_sends_per_client", "10");
        settings->setDefault("emergequeue_limit_diskonly", "16");
        settings->setDefault("emergequeue_limit_generate", "16");
@@ -551,7 +552,6 @@ void set_default_settings()
        settings->setDefault("enable_3d_clouds", "false");
        settings->setDefault("fps_max", "30");
        settings->setDefault("fps_max_unfocused", "10");
-       settings->setDefault("max_objects_per_block", "20");
        settings->setDefault("sqlite_synchronous", "1");
        settings->setDefault("map_compression_level_disk", "-1");
        settings->setDefault("map_compression_level_net", "-1");
index 9234fe6d394d6b67798b9af41bb672101a61e3ff..5c1569f047814a16990e9e6a98ea496c6ae8db23 100644 (file)
@@ -61,7 +61,9 @@ class EmergeThread : public Thread {
 
        void cancelPendingItems();
 
-       static void runCompletionCallbacks(
+protected:
+
+       void runCompletionCallbacks(
                const v3s16 &pos, EmergeAction action,
                const EmergeCallbackList &callbacks);
 
@@ -138,7 +140,7 @@ EmergeParams::EmergeParams(EmergeManager *parent, const BiomeGen *biomegen,
 //// EmergeManager
 ////
 
-EmergeManager::EmergeManager(Server *server)
+EmergeManager::EmergeManager(Server *server, MetricsBackend *mb)
 {
        this->ndef      = server->getNodeDefManager();
        this->biomemgr  = new BiomeManager(server);
@@ -156,6 +158,17 @@ EmergeManager::EmergeManager(Server *server)
 
        enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
 
+       STATIC_ASSERT(ARRLEN(emergeActionStrs) == ARRLEN(m_completed_emerge_counter),
+               enum_size_mismatches);
+       for (u32 i = 0; i < ARRLEN(m_completed_emerge_counter); i++) {
+               std::string help_str("Number of completed emerges with status ");
+               help_str.append(emergeActionStrs[i]);
+               m_completed_emerge_counter[i] = mb->addCounter(
+                       "minetest_emerge_completed", help_str,
+                       {{"status", emergeActionStrs[i]}}
+               );
+       }
+
        s16 nthreads = 1;
        g_settings->getS16NoEx("num_emerge_threads", nthreads);
        // If automatic, leave a proc for the main thread and one for
@@ -202,6 +215,7 @@ EmergeManager::~EmergeManager()
                        delete m_mapgens[i];
        }
 
+       delete biomegen;
        delete biomemgr;
        delete oremgr;
        delete decomgr;
@@ -367,12 +381,6 @@ bool EmergeManager::isBlockInQueue(v3s16 pos)
 //
 
 
-// TODO(hmmmm): Move this to ServerMap
-v3s16 EmergeManager::getContainingChunk(v3s16 blockpos)
-{
-       return getContainingChunk(blockpos, mgparams->chunksize);
-}
-
 // TODO(hmmmm): Move this to ServerMap
 v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize)
 {
@@ -396,17 +404,6 @@ int EmergeManager::getSpawnLevelAtPoint(v2s16 p)
 }
 
 
-int EmergeManager::getGroundLevelAtPoint(v2s16 p)
-{
-       if (m_mapgens.empty() || !m_mapgens[0]) {
-               errorstream << "EmergeManager: getGroundLevelAtPoint() called"
-                       " before mapgen init" << std::endl;
-               return 0;
-       }
-
-       return m_mapgens[0]->getGroundLevelAtPoint(p);
-}
-
 // TODO(hmmmm): Move this to ServerMap
 bool EmergeManager::isBlockUnderground(v3s16 blockpos)
 {
@@ -505,6 +502,12 @@ EmergeThread *EmergeManager::getOptimalThread()
        return m_threads[index];
 }
 
+void EmergeManager::reportCompletedEmerge(EmergeAction action)
+{
+       assert((int)action < ARRLEN(m_completed_emerge_counter));
+       m_completed_emerge_counter[(int)action]->increment();
+}
+
 
 ////
 //// EmergeThread
@@ -556,6 +559,8 @@ void EmergeThread::cancelPendingItems()
 void EmergeThread::runCompletionCallbacks(const v3s16 &pos, EmergeAction action,
        const EmergeCallbackList &callbacks)
 {
+       m_emerge->reportCompletedEmerge(action);
+
        for (size_t i = 0; i != callbacks.size(); i++) {
                EmergeCompletionCallback callback;
                void *param;
@@ -650,12 +655,14 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
                m_server->setAsyncFatalError(e);
        }
 
+       EMERGE_DBG_OUT("ended up with: " << analyze_block(block));
+
        /*
-               Clear generate notifier events
+               Clear mapgen state
        */
+       assert(!m_mapgen->generating);
        m_mapgen->gennotify.clearEvents();
-
-       EMERGE_DBG_OUT("ended up with: " << analyze_block(block));
+       m_mapgen->vm = nullptr;
 
        /*
                Activate the block
@@ -671,19 +678,19 @@ void *EmergeThread::run()
        BEGIN_DEBUG_EXCEPTION_HANDLER
 
        v3s16 pos;
+       std::map<v3s16, MapBlock *> modified_blocks;
 
-       m_map    = (ServerMap *)&(m_server->m_env->getMap());
+       m_map    = &m_server->m_env->getServerMap();
        m_emerge = m_server->m_emerge;
        m_mapgen = m_emerge->m_mapgens[id];
        enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
 
        try {
        while (!stopRequested()) {
-               std::map<v3s16, MapBlock *> modified_blocks;
                BlockEmergeData bedata;
                BlockMakeData bmdata;
                EmergeAction action;
-               MapBlock *block;
+               MapBlock *block = nullptr;
 
                if (!popBlockEmerge(&pos, &bedata)) {
                        m_queue_event.wait();
@@ -706,6 +713,8 @@ void *EmergeThread::run()
                        }
 
                        block = finishGen(pos, &bmdata, &modified_blocks);
+                       if (!block)
+                               action = EMERGE_ERRORED;
                }
 
                runCompletionCallbacks(pos, action, bedata.callbacks);
@@ -715,6 +724,7 @@ void *EmergeThread::run()
 
                if (!modified_blocks.empty())
                        m_server->SetBlocksNotSent(modified_blocks);
+               modified_blocks.clear();
        }
        } catch (VersionMismatchException &e) {
                std::ostringstream err;
@@ -736,6 +746,8 @@ void *EmergeThread::run()
                m_server->setAsyncFatalError(err.str());
        }
 
+       cancelPendingItems();
+
        END_DEBUG_EXCEPTION_HANDLER
        return NULL;
 }
index e2d7279735394e30f9602feb5a098043a90d4473..1bac4b70830d968156be7b636d214541dcde3f5a 100644 (file)
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "network/networkprotocol.h"
 #include "irr_v3d.h"
 #include "util/container.h"
+#include "util/metricsbackend.h"
 #include "mapgen/mapgen.h" // for MapgenParams
 #include "map.h"
 
@@ -69,6 +70,14 @@ enum EmergeAction {
        EMERGE_GENERATED,
 };
 
+const static std::string emergeActionStrs[] = {
+       "cancelled",
+       "errored",
+       "from_memory",
+       "from_disk",
+       "generated",
+};
+
 // Callback
 typedef void (*EmergeCompletionCallback)(
        v3s16 blockpos, EmergeAction action, void *param);
@@ -138,7 +147,7 @@ class EmergeManager {
        MapSettingsManager *map_settings_mgr;
 
        // Methods
-       EmergeManager(Server *server);
+       EmergeManager(Server *server, MetricsBackend *mb);
        ~EmergeManager();
        DISABLE_CLASS_COPY(EmergeManager);
 
@@ -176,13 +185,10 @@ class EmergeManager {
 
        bool isBlockInQueue(v3s16 pos);
 
-       v3s16 getContainingChunk(v3s16 blockpos);
-
        Mapgen *getCurrentMapgen();
 
        // Mapgen helpers methods
        int getSpawnLevelAtPoint(v2s16 p);
-       int getGroundLevelAtPoint(v2s16 p);
        bool isBlockUnderground(v3s16 blockpos);
 
        static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize);
@@ -200,6 +206,9 @@ class EmergeManager {
        u32 m_qlimit_diskonly;
        u32 m_qlimit_generate;
 
+       // Emerge metrics
+       MetricCounterPtr m_completed_emerge_counter[5];
+
        // Managers of various map generation-related components
        // Note that each Mapgen gets a copy(!) of these to work with
        BiomeGen *biomegen;
@@ -221,5 +230,7 @@ class EmergeManager {
 
        bool popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata);
 
+       void reportCompletedEmerge(EmergeAction action);
+
        friend class EmergeThread;
 };
index f10f773cffee64204908ce0438b628639169b293..547b3567eac7b0cdacdb9e6fda2f5666326091af 100644 (file)
@@ -173,6 +173,12 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result)
                        new_nodes.MaxEdge.Z = new_nodes.MinEdge.Z;
                }
 
+               if (new_nodes.MaxEdge.X == S16_MAX ||
+                       new_nodes.MaxEdge.Y == S16_MAX ||
+                       new_nodes.MaxEdge.Z == S16_MAX) {
+                       break; // About to go out of bounds
+               }
+
                // For each untested node
                for (s16 x = new_nodes.MinEdge.X; x <= new_nodes.MaxEdge.X; x++)
                for (s16 y = new_nodes.MinEdge.Y; y <= new_nodes.MaxEdge.Y; y++)
index a07370c0eb54c34f491140e8abea616014092a82..ea00def6aa733cda2792c28ea95d36d4eff13334 100644 (file)
@@ -28,16 +28,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "config.h"
 #include "porting.h"
+#ifndef SERVER
+#include "irr_ptr.h"
+#endif
 
 namespace fs
 {
 
-#ifdef _WIN32 // WINDOWS
+#ifdef _WIN32
+
+/***********
+ * Windows *
+ ***********/
 
+#ifndef _WIN32_WINNT
 #define _WIN32_WINNT 0x0501
+#endif
 #include <windows.h>
 #include <shlwapi.h>
 #include <io.h>
+#include <direct.h>
 
 std::vector<DirListNode> GetDirListing(const std::string &pathstring)
 {
@@ -201,7 +211,11 @@ std::string CreateTempFile()
        return path;
 }
 
-#else // POSIX
+#else
+
+/*********
+ * POSIX *
+ *********/
 
 #include <sys/types.h>
 #include <dirent.h>
@@ -392,6 +406,10 @@ std::string CreateTempFile()
 
 #endif
 
+/****************************
+ * portable implementations *
+ ****************************/
+
 void GetRecursiveDirs(std::vector<std::string> &dirs, const std::string &dir)
 {
        static const std::set<char> chars_to_ignore = { '_', '.' };
@@ -543,6 +561,30 @@ bool CopyDir(const std::string &source, const std::string &target)
        return false;
 }
 
+bool MoveDir(const std::string &source, const std::string &target)
+{
+       infostream << "Moving \"" << source << "\" to \"" << target << "\"" << std::endl;
+
+       // If target exists as empty folder delete, otherwise error
+       if (fs::PathExists(target)) {
+               if (rmdir(target.c_str()) != 0) {
+                       errorstream << "MoveDir: target \"" << target
+                               << "\" exists as file or non-empty folder" << std::endl;
+                       return false;
+               }
+       }
+
+       // Try renaming first which is instant
+       if (fs::Rename(source, target))
+               return true;
+
+       infostream << "MoveDir: rename not possible, will copy instead" << std::endl;
+       bool retval = fs::CopyDir(source, target);
+       if (retval)
+               retval &= fs::RecursiveDelete(source);
+       return retval;
+}
+
 bool PathStartsWith(const std::string &path, const std::string &prefix)
 {
        size_t pathsize = path.size();
@@ -753,69 +795,66 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
        return true;
 }
 
+#ifndef SERVER
 bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string &destination)
 {
-       if (!fs->addFileArchive(filename, false, false, io::EFAT_ZIP)) {
+       // Be careful here not to touch the global file hierarchy in Irrlicht
+       // since this function needs to be thread-safe!
+
+       io::IArchiveLoader *zip_loader = nullptr;
+       for (u32 i = 0; i < fs->getArchiveLoaderCount(); i++) {
+               if (fs->getArchiveLoader(i)->isALoadableFileFormat(io::EFAT_ZIP)) {
+                       zip_loader = fs->getArchiveLoader(i);
+                       break;
+               }
+       }
+       if (!zip_loader) {
+               warningstream << "fs::extractZipFile(): Irrlicht said it doesn't support ZIPs." << std::endl;
                return false;
        }
 
-       sanity_check(fs->getFileArchiveCount() > 0);
-
-       /**********************************************************************/
-       /* WARNING this is not threadsafe!!                                   */
-       /**********************************************************************/
-       io::IFileArchive* opened_zip = fs->getFileArchive(fs->getFileArchiveCount() - 1);
-
+       irr_ptr<io::IFileArchive> opened_zip(zip_loader->createArchive(filename, false, false));
        const io::IFileList* files_in_zip = opened_zip->getFileList();
 
-       unsigned int number_of_files = files_in_zip->getFileCount();
-
-       for (unsigned int i=0; i < number_of_files; i++) {
-               std::string fullpath = destination;
-               fullpath += DIR_DELIM;
+       for (u32 i = 0; i < files_in_zip->getFileCount(); i++) {
+               std::string fullpath = destination + DIR_DELIM;
                fullpath += files_in_zip->getFullFileName(i).c_str();
                std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath);
 
-               if (!files_in_zip->isDirectory(i)) {
-                       if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) {
-                               fs->removeFileArchive(fs->getFileArchiveCount()-1);
-                               return false;
-                       }
-
-                       io::IReadFile* toread = opened_zip->createAndOpenFile(i);
+               if (files_in_zip->isDirectory(i))
+                       continue; // ignore, we create dirs as necessary
 
-                       FILE *targetfile = fopen(fullpath.c_str(),"wb");
+               if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir))
+                       return false;
 
-                       if (targetfile == NULL) {
-                               fs->removeFileArchive(fs->getFileArchiveCount()-1);
-                               return false;
-                       }
+               irr_ptr<io::IReadFile> toread(opened_zip->createAndOpenFile(i));
 
-                       char read_buffer[1024];
-                       long total_read = 0;
+               std::ofstream os(fullpath.c_str(), std::ios::binary);
+               if (!os.good())
+                       return false;
 
-                       while (total_read < toread->getSize()) {
+               char buffer[4096];
+               long total_read = 0;
 
-                               unsigned int bytes_read =
-                                               toread->read(read_buffer,sizeof(read_buffer));
-                               if ((bytes_read == 0 ) ||
-                                       (fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read))
-                               {
-                                       fclose(targetfile);
-                                       fs->removeFileArchive(fs->getFileArchiveCount() - 1);
-                                       return false;
-                               }
-                               total_read += bytes_read;
+               while (total_read < toread->getSize()) {
+                       long bytes_read = toread->read(buffer, sizeof(buffer));
+                       bool error = true;
+                       if (bytes_read != 0) {
+                               os.write(buffer, bytes_read);
+                               error = os.fail();
                        }
-
-                       fclose(targetfile);
+                       if (error) {
+                               os.close();
+                               remove(fullpath.c_str());
+                               return false;
+                       }
+                       total_read += bytes_read;
                }
-
        }
 
-       fs->removeFileArchive(fs->getFileArchiveCount() - 1);
        return true;
 }
+#endif
 
 bool ReadFile(const std::string &path, std::string &out)
 {
@@ -829,7 +868,7 @@ bool ReadFile(const std::string &path, std::string &out)
        is.seekg(0);
        is.read(&out[0], size);
 
-       return true;
+       return !is.fail();
 }
 
 bool Rename(const std::string &from, const std::string &to)
index f72cb0ba2822a8e88e5ded2ec5d666b2c11acd27..3fa2524c36a9d4850fd718631be0f444596633cf 100644 (file)
@@ -24,12 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <vector>
 #include "exceptions.h"
 
-#ifdef _WIN32 // WINDOWS
+#ifdef _WIN32
 #define DIR_DELIM "\\"
 #define DIR_DELIM_CHAR '\\'
 #define FILESYS_CASE_INSENSITIVE true
 #define PATH_DELIM ";"
-#else // POSIX
+#else
 #define DIR_DELIM "/"
 #define DIR_DELIM_CHAR '/'
 #define FILESYS_CASE_INSENSITIVE false
@@ -106,6 +106,10 @@ bool CopyFileContents(const std::string &source, const std::string &target);
 // Omits files and subdirectories that start with a period
 bool CopyDir(const std::string &source, const std::string &target);
 
+// Move directory and all subdirectories
+// Behavior with files/subdirs that start with a period is undefined
+bool MoveDir(const std::string &source, const std::string &target);
+
 // Check if one path is prefix of another
 // For example, "/tmp" is a prefix of "/tmp" and "/tmp/file" but not "/tmp2"
 // Ignores case differences and '/' vs. '\\' on Windows
@@ -133,7 +137,9 @@ const char *GetFilenameFromPath(const char *path);
 
 bool safeWriteToFile(const std::string &path, const std::string &content);
 
+#ifndef SERVER
 bool extractZipFile(irr::io::IFileSystem *fs, const char *filename, const std::string &destination);
+#endif
 
 bool ReadFile(const std::string &path, std::string &out);
 
index 723404106ca1d880bcf82feefe8fbccb7ba2d3fb..4434da369c0ab7bb0d3fa190459737a0012c7023 100644 (file)
@@ -34,6 +34,7 @@ class EmergeManager;
 class Camera;
 class ModChannel;
 class ModMetadata;
+class ModMetadataDatabase;
 
 namespace irr { namespace scene {
        class IAnimatedMesh;
@@ -65,6 +66,8 @@ class IGameDef
        virtual IRollbackManager* getRollbackManager() { return NULL; }
 
        // Shorthands
+       // TODO: these should be made const-safe so that a const IGameDef* is
+       //       actually usable
        IItemDefManager  *idef()     { return getItemDefManager(); }
        const NodeDefManager  *ndef() { return getNodeDefManager(); }
        ICraftDefManager *cdef()     { return getCraftDefManager(); }
@@ -73,9 +76,9 @@ class IGameDef
        virtual const std::vector<ModSpec> &getMods() const = 0;
        virtual const ModSpec* getModSpec(const std::string &modname) const = 0;
        virtual std::string getWorldPath() const { return ""; }
-       virtual std::string getModStoragePath() const = 0;
        virtual bool registerModStorage(ModMetadata *storage) = 0;
        virtual void unregisterModStorage(const std::string &name) = 0;
+       virtual ModMetadataDatabase *getModStorageDatabase() = 0;
 
        virtual bool joinModChannel(const std::string &channel) = 0;
        virtual bool leaveModChannel(const std::string &channel) = 0;
index 5a3654be45e2a406f34f9949903ff6f9f7dfe700..6225fef93e359a12b5e037c9d5f0c66e4b1a33e8 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "config.h" // for USE_GETTEXT
 #include <string>
+#include "porting.h"
 
 #if USE_GETTEXT
        #include <libintl.h>
@@ -47,8 +48,7 @@ void init_gettext(const char *path, const std::string &configured_language,
 
 extern wchar_t *utf8_to_wide_c(const char *str);
 
-// You must free the returned string!
-// The returned string is allocated using new
+// The returned string must be freed using delete[]
 inline const wchar_t *wgettext(const char *str)
 {
        // We must check here that is not an empty string to avoid trying to translate it
@@ -77,3 +77,31 @@ inline std::wstring fwgettext(const char *src, Args&&... args)
        delete[] str;
        return std::wstring(buf);
 }
+
+/**
+ * Returns translated string with format args applied
+ *
+ * @tparam Args Template parameter for format args
+ * @param format Translation source string
+ * @param args Variable format args
+ * @return translated string.
+ */
+template <typename ...Args>
+inline std::string fmtgettext(const char *format, Args&&... args)
+{
+       std::string buf;
+       std::size_t buf_size = 256;
+       buf.resize(buf_size);
+
+       format = gettext(format);
+
+       int len = porting::mt_snprintf(&buf[0], buf_size, format, std::forward<Args>(args)...);
+       if (len <= 0) throw std::runtime_error("gettext format error: " + std::string(format));
+       if ((size_t)len >= buf.size()) {
+               buf.resize(len+1); // extra null byte
+               porting::mt_snprintf(&buf[0], buf.size(), format, std::forward<Args>(args)...);
+       }
+       buf.resize(len); // remove null bytes
+
+       return buf;
+}
index 66efef1d71d02005b0503f6864a35f83dedc11cd..772ff9b50c536ecb01c9b81f744b6420596a3883 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <ctime>
 #include <string>
+#include <mutex>
 
 enum TimePrecision
 {
@@ -30,13 +31,34 @@ enum TimePrecision
        PRECISION_NANO
 };
 
-inline std::string getTimestamp()
+inline struct tm mt_localtime()
 {
+       // initialize the time zone on first invocation
+       static std::once_flag tz_init;
+       std::call_once(tz_init, [] {
+#ifdef _WIN32
+               _tzset();
+#else
+               tzset();
+#endif
+               });
+
+       struct tm ret;
        time_t t = time(NULL);
-       // This is not really thread-safe but it won't break anything
-       // except its own output, so just go with it.
-       struct tm *tm = localtime(&t);
+       // TODO we should check if the function returns NULL, which would mean error
+#ifdef _WIN32
+       localtime_s(&ret, &t);
+#else
+       localtime_r(&t, &ret);
+#endif
+       return ret;
+}
+
+
+inline std::string getTimestamp()
+{
+       const struct tm tm = mt_localtime();
        char cs[20]; // YYYY-MM-DD HH:MM:SS + '\0'
-       strftime(cs, 20, "%Y-%m-%d %H:%M:%S", tm);
+       strftime(cs, 20, "%Y-%m-%d %H:%M:%S", &tm);
        return cs;
 }
index ea6e44ab7b554156c0b0aae304956032d693a896..a5f25c0f3ec511129af6549ccfbad02bd18d83c2 100644 (file)
@@ -1,3 +1,8 @@
+set(extra_gui_SRCS "")
+if(ENABLE_TOUCH)
+       set(extra_gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/touchscreengui.cpp)
+endif()
+
 set(gui_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/cheatMenu.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/guiAnimatedImage.cpp
@@ -26,5 +31,6 @@ set(gui_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/modalMenu.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/profilergraph.cpp
+       ${extra_gui_SRCS}
        PARENT_SCOPE
 )
index 31acfb78045b8e9782255eb2c70b597f3ecc467f..2be82f148a8997fb25f8d2adbbae69429cab926a 100644 (file)
@@ -31,10 +31,6 @@ FontMode CheatMenu::fontStringToEnum(std::string str)
                return FM_Mono;
        else if (str == "FM_Fallback")
                return _FM_Fallback;
-       else if (str == "FM_Simple")
-               return FM_Simple;
-       else if (str == "FM_SimpleMono")
-               return FM_SimpleMono;
        else if (str == "FM_MaxMode")
                return FM_MaxMode;
        else if (str == "FM_Unspecified")
index 21c1e88cfe8c439f3ac1da43f467a63cd868c694..85e8707711dc1b089042d9d8c4ef6ecd55e9c4e6 100644 (file)
@@ -44,7 +44,7 @@ void GUIBackgroundImage::draw()
 
        core::rect<s32> rect = AbsoluteRect;
        if (m_autoclip)
-               rect.LowerRightCorner += Parent->getAbsolutePosition().getSize();
+               rect.LowerRightCorner += Parent->getAbsoluteClippingRect().getSize();
 
        video::IVideoDriver *driver = Environment->getVideoDriver();
 
index d6dbddf54afb0920014af99b0a45bd164d3e2d9c..ba95b81c39e50d3a8971ff2fe51035bc3abf2dea 100644 (file)
@@ -632,85 +632,6 @@ bool GUIButton::isDrawingBorder() const
 }\r
 \r
 \r
-//! Writes attributes of the element.\r
-void GUIButton::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const\r
-{\r
-       IGUIButton::serializeAttributes(out,options);\r
-\r
-       out->addBool    ("PushButton",          IsPushButton );\r
-       if (IsPushButton)\r
-               out->addBool("Pressed",             Pressed);\r
-\r
-       for ( u32 i=0; i<(u32)EGBIS_COUNT; ++i )\r
-       {\r
-               if ( ButtonImages[i].Texture )\r
-               {\r
-                       core::stringc name( GUIButtonImageStateNames[i] );\r
-                       out->addTexture(name.c_str(), ButtonImages[i].Texture);\r
-                       name += "Rect";\r
-                       out->addRect(name.c_str(), ButtonImages[i].SourceRect);\r
-               }\r
-       }\r
-\r
-       out->addBool    ("UseAlphaChannel",     UseAlphaChannel);\r
-       out->addBool    ("Border",                  DrawBorder);\r
-       out->addBool    ("ScaleImage",          ScaleImage);\r
-\r
-       for ( u32 i=0; i<(u32)EGBS_COUNT; ++i )\r
-       {\r
-               if ( ButtonSprites[i].Index >= 0 )\r
-               {\r
-                       core::stringc nameIndex( GUIButtonStateNames[i] );\r
-                       nameIndex += "Index";\r
-                       out->addInt(nameIndex.c_str(), ButtonSprites[i].Index );\r
-\r
-                       core::stringc nameColor( GUIButtonStateNames[i] );\r
-                       nameColor += "Color";\r
-                       out->addColor(nameColor.c_str(), ButtonSprites[i].Color );\r
-\r
-                       core::stringc nameLoop( GUIButtonStateNames[i] );\r
-                       nameLoop += "Loop";\r
-                       out->addBool(nameLoop.c_str(), ButtonSprites[i].Loop );\r
-\r
-                       core::stringc nameScale( GUIButtonStateNames[i] );\r
-                       nameScale += "Scale";\r
-                       out->addBool(nameScale.c_str(), ButtonSprites[i].Scale );\r
-               }\r
-       }\r
-\r
-       //   out->addString  ("OverrideFont",   OverrideFont);\r
-}\r
-\r
-\r
-//! Reads attributes of the element\r
-void GUIButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)\r
-{\r
-       IGUIButton::deserializeAttributes(in,options);\r
-\r
-       IsPushButton    = in->getAttributeAsBool("PushButton");\r
-       Pressed         = IsPushButton ? in->getAttributeAsBool("Pressed") : false;\r
-\r
-       core::rect<s32> rec = in->getAttributeAsRect("ImageRect");\r
-       if (rec.isValid())\r
-               setImage( in->getAttributeAsTexture("Image"), rec);\r
-       else\r
-               setImage( in->getAttributeAsTexture("Image") );\r
-\r
-       rec = in->getAttributeAsRect("PressedImageRect");\r
-       if (rec.isValid())\r
-               setPressedImage( in->getAttributeAsTexture("PressedImage"), rec);\r
-       else\r
-               setPressedImage( in->getAttributeAsTexture("PressedImage") );\r
-\r
-       setDrawBorder(in->getAttributeAsBool("Border"));\r
-       setUseAlphaChannel(in->getAttributeAsBool("UseAlphaChannel"));\r
-       setScaleImage(in->getAttributeAsBool("ScaleImage"));\r
-\r
-       //   setOverrideFont(in->getAttributeAsString("OverrideFont"));\r
-\r
-       updateAbsolutePosition();\r
-}\r
-\r
 // PATCH\r
 GUIButton* GUIButton::addButton(IGUIEnvironment *environment,\r
                const core::rect<s32>& rectangle, ISimpleTextureSource *tsrc,\r
index 834405f51093bd3bb12fd453f9a3a91ef72ec1b0..ee9bb6f2196412fcef5a09f51bee845d3488f2ec 100644 (file)
@@ -221,14 +221,6 @@ class GUIButton : public gui::IGUIButton
                return ClickControlState;\r
        }\r
 \r
-       //! Writes attributes of the element.\r
-       virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const override;\r
-\r
-       //! Reads attributes of the element\r
-       virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) override;\r
-\r
-\r
-\r
        void setColor(video::SColor color);\r
        // PATCH\r
        //! Set element properties from a StyleSpec corresponding to the button state\r
index 0610c85cc744b34488c5ca39da2a6748fca304d9..01e10ea2ea213df4236730b1f2c6da1792d5e9e4 100644 (file)
@@ -30,12 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "client/fontengine.h"
 #include "log.h"
 #include "gettext.h"
+#include "irrlicht_changes/CGUITTFont.h"
 #include <string>
 
-#if USE_FREETYPE
-       #include "irrlicht_changes/CGUITTFont.h"
-#endif
-
 inline u32 clamp_u8(s32 value)
 {
        return (u32) MYMIN(MYMAX(value, 0), 255);
@@ -328,19 +325,16 @@ void GUIChatConsole::drawText()
                        core::rect<s32> destrect(
                                x, y, x + m_fontsize.X * fragment.text.size(), y + m_fontsize.Y);
 
-#if USE_FREETYPE
                        if (m_font->getType() == irr::gui::EGFT_CUSTOM) {
-                               // Draw colored text if FreeType is enabled
-                               irr::gui::CGUITTFont *tmp = dynamic_cast<irr::gui::CGUITTFont *>(m_font);
+                               // Draw colored text if possible
+                               gui::CGUITTFont *tmp = static_cast<gui::CGUITTFont*>(m_font);
                                tmp->draw(
                                        fragment.text,
                                        destrect,
                                        false,
                                        false,
                                        &AbsoluteClippingRect);
-                       } else
-#endif
-                       {
+                       } else {
                                // Otherwise use standard text
                                m_font->draw(
                                        fragment.text.c_str(),
index 4ca9a64ed5d41c7a0d18333b60f5dc531ce7ca89..b8887a4af1c5cc745df89480cb0d39c53f410220 100644 (file)
@@ -28,6 +28,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "guiEditBoxWithScrollbar.h"
 #include "porting.h"
 
+#ifdef HAVE_TOUCHSCREENGUI
+       #include "client/renderingengine.h"
+#endif
+
 #include "gettext.h"
 
 // Continuing from guiPasswordChange.cpp
@@ -45,7 +49,7 @@ GUIConfirmRegistration::GUIConfirmRegistration(gui::IGUIEnvironment *env,
                m_client(client), m_playername(playername), m_password(password),
                m_aborted(aborted), m_tsrc(tsrc)
 {
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        m_touchscreen_visible = false;
 #endif
 }
@@ -73,8 +77,8 @@ void GUIConfirmRegistration::regenerateGui(v2u32 screensize)
        /*
                Calculate new sizes and positions
        */
-#ifdef __ANDROID__
-       const float s = m_gui_scale * porting::getDisplayDensity() / 2;
+#ifdef HAVE_TOUCHSCREENGUI
+       const float s = m_gui_scale * RenderingEngine::getDisplayDensity() / 2;
 #else
        const float s = m_gui_scale;
 #endif
index 8459107cd1b80fbe59ba6c0d77d1f2117e1839d7..4a0f5013dfb030f0d4e16bc97eb9f639f16281e4 100644 (file)
@@ -846,54 +846,3 @@ void GUIEditBox::updateVScrollBar()
                }
        }
 }
-
-void GUIEditBox::deserializeAttributes(
-               io::IAttributes *in, io::SAttributeReadWriteOptions *options = 0)
-{
-       IGUIEditBox::deserializeAttributes(in, options);
-
-       setOverrideColor(in->getAttributeAsColor("OverrideColor"));
-       enableOverrideColor(in->getAttributeAsBool("OverrideColorEnabled"));
-       setMax(in->getAttributeAsInt("MaxChars"));
-       setWordWrap(in->getAttributeAsBool("WordWrap"));
-       setMultiLine(in->getAttributeAsBool("MultiLine"));
-       setAutoScroll(in->getAttributeAsBool("AutoScroll"));
-       core::stringw ch = in->getAttributeAsStringW("PasswordChar");
-
-       if (ch.empty())
-               setPasswordBox(in->getAttributeAsBool("PasswordBox"));
-       else
-               setPasswordBox(in->getAttributeAsBool("PasswordBox"), ch[0]);
-
-       setTextAlignment((EGUI_ALIGNMENT)in->getAttributeAsEnumeration(
-                                        "HTextAlign", GUIAlignmentNames),
-                       (EGUI_ALIGNMENT)in->getAttributeAsEnumeration(
-                                       "VTextAlign", GUIAlignmentNames));
-
-       setWritable(in->getAttributeAsBool("Writable"));
-       // setOverrideFont(in->getAttributeAsFont("OverrideFont"));
-}
-
-//! Writes attributes of the element.
-void GUIEditBox::serializeAttributes(
-               io::IAttributes *out, io::SAttributeReadWriteOptions *options = 0) const
-{
-       // IGUIEditBox::serializeAttributes(out,options);
-
-       out->addBool("OverrideColorEnabled", m_override_color_enabled);
-       out->addColor("OverrideColor", m_override_color);
-       // out->addFont("OverrideFont",m_override_font);
-       out->addInt("MaxChars", m_max);
-       out->addBool("WordWrap", m_word_wrap);
-       out->addBool("MultiLine", m_multiline);
-       out->addBool("AutoScroll", m_autoscroll);
-       out->addBool("PasswordBox", m_passwordbox);
-       core::stringw ch = L" ";
-       ch[0] = m_passwordchar;
-       out->addString("PasswordChar", ch.c_str());
-       out->addEnum("HTextAlign", m_halign, GUIAlignmentNames);
-       out->addEnum("VTextAlign", m_valign, GUIAlignmentNames);
-       out->addBool("Writable", m_writable);
-
-       IGUIEditBox::serializeAttributes(out, options);
-}
index 2a5c911bc397228c4ed0dc383db44ca73f7c6a50..4c7413f549544823e0bd6643b503e8ebd2b4975f 100644 (file)
@@ -130,14 +130,6 @@ class GUIEditBox : public IGUIEditBox
        //! called if an event happened.
        virtual bool OnEvent(const SEvent &event);
 
-       //! Writes attributes of the element.
-       virtual void serializeAttributes(io::IAttributes *out,
-                       io::SAttributeReadWriteOptions *options) const;
-
-       //! Reads attributes of the element
-       virtual void deserializeAttributes(
-                       io::IAttributes *in, io::SAttributeReadWriteOptions *options);
-
        virtual bool acceptsIME() { return isEnabled() && m_writable; };
 
 protected:
index fb4bc2a0b2b14e9c10089c666395b2de18d67d2b..1b7f7832a517c5f9eff79742fe8372b65bd9c631 100644 (file)
@@ -652,26 +652,6 @@ void GUIEditBoxWithScrollBar::setBackgroundColor(const video::SColor &bg_color)
        m_bg_color_used = true;
 }
 
-//! Writes attributes of the element.
-void GUIEditBoxWithScrollBar::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options = 0) const
-{
-       out->addBool("Border", m_border);
-       out->addBool("Background", m_background);
-       // out->addFont("OverrideFont", OverrideFont);
-
-       GUIEditBox::serializeAttributes(out, options);
-}
-
-
-//! Reads attributes of the element
-void GUIEditBoxWithScrollBar::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options = 0)
-{
-       GUIEditBox::deserializeAttributes(in, options);
-
-       setDrawBorder(in->getAttributeAsBool("Border"));
-       setDrawBackground(in->getAttributeAsBool("Background"));
-}
-
 bool GUIEditBoxWithScrollBar::isDrawBackgroundEnabled() const { return false; }
 bool GUIEditBoxWithScrollBar::isDrawBorderEnabled() const { return false; }
 void GUIEditBoxWithScrollBar::setCursorChar(const wchar_t cursorChar) { }
index 3f7450dcb7d7edde8a38f3bea6fbf4414b131316..cea482fc26be4f4306a993a16346b4207da3166b 100644 (file)
@@ -31,12 +31,6 @@ class GUIEditBoxWithScrollBar : public GUIEditBox
        //! Change the background color
        virtual void setBackgroundColor(const video::SColor &bg_color);
 
-       //! Writes attributes of the element.
-       virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
-
-       //! Reads attributes of the element
-       virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
-
        virtual bool isDrawBackgroundEnabled() const;
        virtual bool isDrawBorderEnabled() const;
        virtual void setCursorChar(const wchar_t cursorChar);
index c39c3ee0dcd7dcf9817ca8e088a3d9d484741300..b65b313047d8242988d54e8382abadd17a16d863 100644 (file)
@@ -104,16 +104,22 @@ void MenuMusicFetcher::fetchSounds(const std::string &name,
        if(m_fetched.count(name))
                return;
        m_fetched.insert(name);
-       std::string base;
-       base = porting::path_share + DIR_DELIM + "sounds";
-       dst_paths.insert(base + DIR_DELIM + name + ".ogg");
-       int i;
-       for(i=0; i<10; i++)
-               dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
-       base = porting::path_user + DIR_DELIM + "sounds";
-       dst_paths.insert(base + DIR_DELIM + name + ".ogg");
-       for(i=0; i<10; i++)
-               dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
+       std::vector<fs::DirListNode> list;
+       // Reusable local function
+       auto add_paths = [&dst_paths](const std::string name, const std::string base = "") {
+               dst_paths.insert(base + name + ".ogg");
+               for (int i = 0; i < 10; i++)
+                       dst_paths.insert(base + name + "." + itos(i) + ".ogg");
+       };
+       // Allow full paths
+       if (name.find(DIR_DELIM_CHAR) != std::string::npos) {
+               add_paths(name);
+       } else {
+               std::string share_prefix = porting::path_share + DIR_DELIM;
+               add_paths(name, share_prefix + "sounds" + DIR_DELIM);
+               std::string user_prefix = porting::path_user + DIR_DELIM;
+               add_paths(name, user_prefix + "sounds" + DIR_DELIM);
+       }
 }
 
 /******************************************************************************/
index 797fd3ff6b731495a192929db637a2255ac9b197..f3570ccaf099f52cb8f653a37e3c102dc9bbb78b 100644 (file)
@@ -81,6 +81,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
                        " specified: \"" << parts[b] << "\"" << std::endl;                              \
                        return;                                                                                                                 \
        }
+
+#define MY_CHECKCLIENT(a) \
+       if (!m_client) { \
+               errorstream << "Attempted to use element " << a << " with m_client == nullptr." << std::endl; \
+               return; \
+       }
+
 /*
        GUIFormSpecMenu
 */
@@ -130,8 +137,6 @@ GUIFormSpecMenu::~GUIFormSpecMenu()
                checkbox_it.second->drop();
        for (auto &scrollbar_it : m_scrollbars)
                scrollbar_it.second->drop();
-       for (auto &background_it : m_backgrounds)
-               background_it->drop();
        for (auto &tooltip_rect_it : m_tooltip_rects)
                tooltip_rect_it.first->drop();
        for (auto &clickthrough_it : m_clickthrough_elements)
@@ -294,8 +299,20 @@ v2s32 GUIFormSpecMenu::getRealCoordinateGeometry(const std::vector<std::string>
        return v2s32(stof(v_geom[0]) * imgsize.X, stof(v_geom[1]) * imgsize.Y);
 }
 
+bool GUIFormSpecMenu::precheckElement(const std::string &name, const std::string &element,
+       size_t args_min, size_t args_max, std::vector<std::string> &parts)
+{
+       parts = split(element, ';');
+       if (parts.size() >= args_min && (parts.size() <= args_max || m_formspec_version > FORMSPEC_API_VERSION))
+               return true;
+
+       errorstream << "Invalid " << name << " element(" << parts.size() << "): '" << element << "'" << std::endl;
+       return false;
+}
+
 void GUIFormSpecMenu::parseSize(parserData* data, const std::string &element)
 {
+       // Note: do not use precheckElement due to "," separator.
        std::vector<std::string> parts = split(element,',');
 
        if (((parts.size() == 2) || parts.size() == 3) ||
@@ -308,7 +325,7 @@ void GUIFormSpecMenu::parseSize(parserData* data, const std::string &element)
                data->invsize.Y = MYMAX(0, stof(parts[1]));
 
                lockSize(false);
-#ifndef __ANDROID__
+#ifndef HAVE_TOUCHSCREENGUI
                if (parts.size() == 3) {
                        if (parts[2] == "true") {
                                lockSize(true,v2u32(800,600));
@@ -349,14 +366,9 @@ void GUIFormSpecMenu::parseContainerEnd(parserData* data)
 
 void GUIFormSpecMenu::parseScrollContainer(parserData *data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
-
-       if (parts.size() < 4 ||
-                       (parts.size() > 5 && m_formspec_version <= FORMSPEC_API_VERSION)) {
-               errorstream << "Invalid scroll_container start element (" << parts.size()
-                               << "): '" << element << "'" << std::endl;
+       std::vector<std::string> parts;
+       if (!precheckElement("scroll_container start", element, 4, 5, parts))
                return;
-       }
 
        std::vector<std::string> v_pos  = split(parts[0], ',');
        std::vector<std::string> v_geom = split(parts[1], ',');
@@ -445,105 +457,95 @@ void GUIFormSpecMenu::parseScrollContainerEnd(parserData *data)
 
 void GUIFormSpecMenu::parseList(parserData *data, const std::string &element)
 {
-       if (m_client == 0) {
-               warningstream<<"invalid use of 'list' with m_client==0"<<std::endl;
-               return;
-       }
+       MY_CHECKCLIENT("list");
 
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("list", element, 4, 5, parts))
+               return;
 
-       if (((parts.size() == 4) || (parts.size() == 5)) ||
-               ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::string location = parts[0];
-               std::string listname = parts[1];
-               std::vector<std::string> v_pos  = split(parts[2],',');
-               std::vector<std::string> v_geom = split(parts[3],',');
-               std::string startindex;
-               if (parts.size() == 5)
-                       startindex = parts[4];
+       std::string location = parts[0];
+       std::string listname = parts[1];
+       std::vector<std::string> v_pos  = split(parts[2],',');
+       std::vector<std::string> v_geom = split(parts[3],',');
+       std::string startindex;
+       if (parts.size() == 5)
+               startindex = parts[4];
 
-               MY_CHECKPOS("list",2);
-               MY_CHECKGEOM("list",3);
+       MY_CHECKPOS("list",2);
+       MY_CHECKGEOM("list",3);
 
-               InventoryLocation loc;
+       InventoryLocation loc;
 
-               if (location == "context" || location == "current_name")
-                       loc = m_current_inventory_location;
-               else
-                       loc.deSerialize(location);
+       if (location == "context" || location == "current_name")
+               loc = m_current_inventory_location;
+       else
+               loc.deSerialize(location);
 
-               v2s32 geom;
-               geom.X = stoi(v_geom[0]);
-               geom.Y = stoi(v_geom[1]);
+       v2s32 geom;
+       geom.X = stoi(v_geom[0]);
+       geom.Y = stoi(v_geom[1]);
 
-               s32 start_i = 0;
-               if (!startindex.empty())
-                       start_i = stoi(startindex);
+       s32 start_i = 0;
+       if (!startindex.empty())
+               start_i = stoi(startindex);
 
-               if (geom.X < 0 || geom.Y < 0 || start_i < 0) {
-                       errorstream << "Invalid list element: '" << element << "'"  << std::endl;
-                       return;
-               }
+       if (geom.X < 0 || geom.Y < 0 || start_i < 0) {
+               errorstream << "Invalid list element: '" << element << "'"  << std::endl;
+               return;
+       }
 
-               if (!data->explicit_size)
-                       warningstream << "invalid use of list without a size[] element" << std::endl;
+       if (!data->explicit_size)
+               warningstream << "invalid use of list without a size[] element" << std::endl;
 
-               FieldSpec spec(
-                       "",
-                       L"",
-                       L"",
-                       258 + m_fields.size(),
-                       3
-               );
+       FieldSpec spec(
+               "",
+               L"",
+               L"",
+               258 + m_fields.size(),
+               3
+       );
 
-               auto style = getDefaultStyleForElement("list", spec.fname);
+       auto style = getDefaultStyleForElement("list", spec.fname);
 
-               v2f32 slot_scale = style.getVector2f(StyleSpec::SIZE, v2f32(0, 0));
-               v2f32 slot_size(
-                       slot_scale.X <= 0 ? imgsize.X : std::max<f32>(slot_scale.X * imgsize.X, 1),
-                       slot_scale.Y <= 0 ? imgsize.Y : std::max<f32>(slot_scale.Y * imgsize.Y, 1)
-               );
+       v2f32 slot_scale = style.getVector2f(StyleSpec::SIZE, v2f32(0, 0));
+       v2f32 slot_size(
+               slot_scale.X <= 0 ? imgsize.X : std::max<f32>(slot_scale.X * imgsize.X, 1),
+               slot_scale.Y <= 0 ? imgsize.Y : std::max<f32>(slot_scale.Y * imgsize.Y, 1)
+       );
 
-               v2f32 slot_spacing = style.getVector2f(StyleSpec::SPACING, v2f32(-1, -1));
-               v2f32 default_spacing = data->real_coordinates ?
-                               v2f32(imgsize.X * 0.25f, imgsize.Y * 0.25f) :
-                               v2f32(spacing.X - imgsize.X, spacing.Y - imgsize.Y);
+       v2f32 slot_spacing = style.getVector2f(StyleSpec::SPACING, v2f32(-1, -1));
+       v2f32 default_spacing = data->real_coordinates ?
+                       v2f32(imgsize.X * 0.25f, imgsize.Y * 0.25f) :
+                       v2f32(spacing.X - imgsize.X, spacing.Y - imgsize.Y);
 
-               slot_spacing.X = slot_spacing.X < 0 ? default_spacing.X :
-                               imgsize.X * slot_spacing.X;
-               slot_spacing.Y = slot_spacing.Y < 0 ? default_spacing.Y :
-                               imgsize.Y * slot_spacing.Y;
+       slot_spacing.X = slot_spacing.X < 0 ? default_spacing.X :
+                       imgsize.X * slot_spacing.X;
+       slot_spacing.Y = slot_spacing.Y < 0 ? default_spacing.Y :
+                       imgsize.Y * slot_spacing.Y;
 
-               slot_spacing += slot_size;
+       slot_spacing += slot_size;
 
-               v2s32 pos = data->real_coordinates ? getRealCoordinateBasePos(v_pos) :
-                               getElementBasePos(&v_pos);
+       v2s32 pos = data->real_coordinates ? getRealCoordinateBasePos(v_pos) :
+                       getElementBasePos(&v_pos);
 
-               core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y,
-                               pos.X + (geom.X - 1) * slot_spacing.X + slot_size.X,
-                               pos.Y + (geom.Y - 1) * slot_spacing.Y + slot_size.Y);
+       core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y,
+                       pos.X + (geom.X - 1) * slot_spacing.X + slot_size.X,
+                       pos.Y + (geom.Y - 1) * slot_spacing.Y + slot_size.Y);
 
-               GUIInventoryList *e = new GUIInventoryList(Environment, data->current_parent,
-                               spec.fid, rect, m_invmgr, loc, listname, geom, start_i,
-                               v2s32(slot_size.X, slot_size.Y), slot_spacing, this,
-                               data->inventorylist_options, m_font);
+       GUIInventoryList *e = new GUIInventoryList(Environment, data->current_parent,
+                       spec.fid, rect, m_invmgr, loc, listname, geom, start_i,
+                       v2s32(slot_size.X, slot_size.Y), slot_spacing, this,
+                       data->inventorylist_options, m_font);
 
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
 
-               m_inventorylists.push_back(e);
-               m_fields.push_back(spec);
-               return;
-       }
-       errorstream<< "Invalid list element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       m_inventorylists.push_back(e);
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseListRing(parserData *data, const std::string &element)
 {
-       if (m_client == 0) {
-               errorstream << "WARNING: invalid use of 'listring' with m_client==0" << std::endl;
-               return;
-       }
+       MY_CHECKCLIENT("listring");
 
        std::vector<std::string> parts = split(element, ';');
 
@@ -578,157 +580,150 @@ void GUIFormSpecMenu::parseListRing(parserData *data, const std::string &element
 
 void GUIFormSpecMenu::parseCheckbox(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
-
-       if (((parts.size() >= 3) && (parts.size() <= 4)) ||
-               ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::string name = parts[1];
-               std::string label = parts[2];
-               std::string selected;
+       std::vector<std::string> parts;
+       if (!precheckElement("checkbox", element, 3, 4, parts))
+               return;
 
-               if (parts.size() >= 4)
-                       selected = parts[3];
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::string name = parts[1];
+       std::string label = parts[2];
+       std::string selected;
 
-               MY_CHECKPOS("checkbox",0);
+       if (parts.size() >= 4)
+               selected = parts[3];
 
-               bool fselected = false;
+       MY_CHECKPOS("checkbox",0);
 
-               if (selected == "true")
-                       fselected = true;
+       bool fselected = false;
 
-               std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label)));
-               const core::dimension2d<u32> label_size = m_font->getDimension(wlabel.c_str());
-               s32 cb_size = Environment->getSkin()->getSize(gui::EGDS_CHECK_BOX_WIDTH);
-               s32 y_center = (std::max(label_size.Height, (u32)cb_size) + 1) / 2;
+       if (selected == "true")
+               fselected = true;
 
-               v2s32 pos;
-               core::rect<s32> rect;
+       std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label)));
+       const core::dimension2d<u32> label_size = m_font->getDimension(wlabel.c_str());
+       s32 cb_size = Environment->getSkin()->getSize(gui::EGDS_CHECK_BOX_WIDTH);
+       s32 y_center = (std::max(label_size.Height, (u32)cb_size) + 1) / 2;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
+       v2s32 pos;
+       core::rect<s32> rect;
 
-                       rect = core::rect<s32>(
-                                       pos.X,
-                                       pos.Y - y_center,
-                                       pos.X + label_size.Width + cb_size + 7,
-                                       pos.Y + y_center
-                               );
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       rect = core::rect<s32>(
-                                       pos.X,
-                                       pos.Y + imgsize.Y / 2 - y_center,
-                                       pos.X + label_size.Width + cb_size + 7,
-                                       pos.Y + imgsize.Y / 2 + y_center
-                               );
-               }
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
 
-               FieldSpec spec(
-                               name,
-                               wlabel, //Needed for displaying text on MSVC
-                               wlabel,
-                               258+m_fields.size()
+               rect = core::rect<s32>(
+                               pos.X,
+                               pos.Y - y_center,
+                               pos.X + label_size.Width + cb_size + 7,
+                               pos.Y + y_center
+                       );
+       } else {
+               pos = getElementBasePos(&v_pos);
+               rect = core::rect<s32>(
+                               pos.X,
+                               pos.Y + imgsize.Y / 2 - y_center,
+                               pos.X + label_size.Width + cb_size + 7,
+                               pos.Y + imgsize.Y / 2 + y_center
                        );
+       }
 
-               spec.ftype = f_CheckBox;
+       FieldSpec spec(
+                       name,
+                       wlabel, //Needed for displaying text on MSVC
+                       wlabel,
+                       258+m_fields.size()
+               );
 
-               gui::IGUICheckBox *e = Environment->addCheckBox(fselected, rect,
-                               data->current_parent, spec.fid, spec.flabel.c_str());
+       spec.ftype = f_CheckBox;
 
-               auto style = getDefaultStyleForElement("checkbox", name);
+       gui::IGUICheckBox *e = Environment->addCheckBox(fselected, rect,
+                       data->current_parent, spec.fid, spec.flabel.c_str());
 
-               spec.sound = style.get(StyleSpec::Property::SOUND, "");
+       auto style = getDefaultStyleForElement("checkbox", name);
 
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       spec.sound = style.get(StyleSpec::Property::SOUND, "");
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
 
-               e->grab();
-               m_checkboxes.emplace_back(spec, e);
-               m_fields.push_back(spec);
-               return;
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
        }
-       errorstream<< "Invalid checkbox element(" << parts.size() << "): '" << element << "'"  << std::endl;
+
+       e->grab();
+       m_checkboxes.emplace_back(spec, e);
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseScrollBar(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
-
-       if (parts.size() >= 5) {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string name = parts[3];
-               std::string value = parts[4];
+       std::vector<std::string> parts;
+       if (!precheckElement("scrollbar", element, 5, 5, parts))
+               return;
 
-               MY_CHECKPOS("scrollbar",0);
-               MY_CHECKGEOM("scrollbar",1);
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string name = parts[3];
+       std::string value = parts[4];
 
-               v2s32 pos;
-               v2s32 dim;
+       MY_CHECKPOS("scrollbar",0);
+       MY_CHECKGEOM("scrollbar",1);
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       dim = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       dim.X = stof(v_geom[0]) * spacing.X;
-                       dim.Y = stof(v_geom[1]) * spacing.Y;
-               }
+       v2s32 pos;
+       v2s32 dim;
 
-               core::rect<s32> rect =
-                               core::rect<s32>(pos.X, pos.Y, pos.X + dim.X, pos.Y + dim.Y);
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               dim = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               dim.X = stof(v_geom[0]) * spacing.X;
+               dim.Y = stof(v_geom[1]) * spacing.Y;
+       }
 
-               FieldSpec spec(
-                               name,
-                               L"",
-                               L"",
-                               258+m_fields.size()
-                       );
+       core::rect<s32> rect =
+                       core::rect<s32>(pos.X, pos.Y, pos.X + dim.X, pos.Y + dim.Y);
 
-               bool is_horizontal = true;
+       FieldSpec spec(
+                       name,
+                       L"",
+                       L"",
+                       258+m_fields.size()
+               );
 
-               if (parts[2] == "vertical")
-                       is_horizontal = false;
+       bool is_horizontal = true;
 
-               spec.ftype = f_ScrollBar;
-               spec.send  = true;
-               GUIScrollBar *e = new GUIScrollBar(Environment, data->current_parent,
-                               spec.fid, rect, is_horizontal, true);
+       if (parts[2] == "vertical")
+               is_horizontal = false;
 
-               auto style = getDefaultStyleForElement("scrollbar", name);
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
-               e->setArrowsVisible(data->scrollbar_options.arrow_visiblity);
+       spec.ftype = f_ScrollBar;
+       spec.send  = true;
+       GUIScrollBar *e = new GUIScrollBar(Environment, data->current_parent,
+                       spec.fid, rect, is_horizontal, true);
 
-               s32 max = data->scrollbar_options.max;
-               s32 min = data->scrollbar_options.min;
+       auto style = getDefaultStyleForElement("scrollbar", name);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       e->setArrowsVisible(data->scrollbar_options.arrow_visiblity);
 
-               e->setMax(max);
-               e->setMin(min);
+       s32 max = data->scrollbar_options.max;
+       s32 min = data->scrollbar_options.min;
 
-               e->setPos(stoi(parts[4]));
+       e->setMax(max);
+       e->setMin(min);
 
-               e->setSmallStep(data->scrollbar_options.small_step);
-               e->setLargeStep(data->scrollbar_options.large_step);
+       e->setPos(stoi(parts[4]));
 
-               s32 scrollbar_size = is_horizontal ? dim.X : dim.Y;
+       e->setSmallStep(data->scrollbar_options.small_step);
+       e->setLargeStep(data->scrollbar_options.large_step);
 
-               e->setPageSize(scrollbar_size * (max - min + 1) / data->scrollbar_options.thumb_size);
+       s32 scrollbar_size = is_horizontal ? dim.X : dim.Y;
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       e->setPageSize(scrollbar_size * (max - min + 1) / data->scrollbar_options.thumb_size);
 
-               m_scrollbars.emplace_back(spec,e);
-               m_fields.push_back(spec);
-               return;
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
        }
-       errorstream << "Invalid scrollbar element(" << parts.size() << "): '" << element
-               << "'" << std::endl;
+
+       m_scrollbars.emplace_back(spec,e);
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseScrollBarOptions(parserData* data, const std::string &element)
@@ -786,11 +781,11 @@ void GUIFormSpecMenu::parseScrollBarOptions(parserData* data, const std::string
 
 void GUIFormSpecMenu::parseImage(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("image", element, 2, 3, parts))
+               return;
 
-       if ((parts.size() == 3) ||
-               ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
+       if (parts.size() >= 3) {
                std::vector<std::string> v_pos = split(parts[0],',');
                std::vector<std::string> v_geom = split(parts[1],',');
                std::string name = unescape_string(parts[2]);
@@ -842,54 +837,47 @@ void GUIFormSpecMenu::parseImage(parserData* data, const std::string &element)
                return;
        }
 
-       if (parts.size() == 2) {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::string name = unescape_string(parts[1]);
-
-               MY_CHECKPOS("image", 0);
+       // Else: 2 arguments in "parts"
 
-               v2s32 pos = getElementBasePos(&v_pos);
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::string name = unescape_string(parts[1]);
 
-               if (!data->explicit_size)
-                       warningstream<<"invalid use of image without a size[] element"<<std::endl;
+       MY_CHECKPOS("image", 0);
 
-               video::ITexture *texture = m_tsrc->getTexture(name);
-               if (!texture) {
-                       errorstream << "GUIFormSpecMenu::parseImage() Unable to load texture:"
-                                       << std::endl << "\t" << name << std::endl;
-                       return;
-               }
+       v2s32 pos = getElementBasePos(&v_pos);
 
-               FieldSpec spec(
-                       name,
-                       L"",
-                       L"",
-                       258 + m_fields.size()
-               );
-               gui::IGUIImage *e = Environment->addImage(texture, pos, true,
-                               data->current_parent, spec.fid, 0);
-               auto style = getDefaultStyleForElement("image", spec.fname);
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3));
-               m_fields.push_back(spec);
+       if (!data->explicit_size)
+               warningstream<<"invalid use of image without a size[] element"<<std::endl;
 
-               // images should let events through
-               e->grab();
-               m_clickthrough_elements.push_back(e);
+       video::ITexture *texture = m_tsrc->getTexture(name);
+       if (!texture) {
+               errorstream << "GUIFormSpecMenu::parseImage() Unable to load texture:"
+                               << std::endl << "\t" << name << std::endl;
                return;
        }
-       errorstream<< "Invalid image element(" << parts.size() << "): '" << element << "'"  << std::endl;
+
+       FieldSpec spec(
+               name,
+               L"",
+               L"",
+               258 + m_fields.size()
+       );
+       gui::IGUIImage *e = Environment->addImage(texture, pos, true,
+                       data->current_parent, spec.fid, 0);
+       auto style = getDefaultStyleForElement("image", spec.fname);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3));
+       m_fields.push_back(spec);
+
+       // images should let events through
+       e->grab();
+       m_clickthrough_elements.push_back(e);
 }
 
 void GUIFormSpecMenu::parseAnimatedImage(parserData *data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
-
-       if (parts.size() != 6 && parts.size() != 7 &&
-                       !(parts.size() > 7 && m_formspec_version > FORMSPEC_API_VERSION)) {
-               errorstream << "Invalid animated_image element(" << parts.size()
-                       << "): '" << element << "'" << std::endl;
+       std::vector<std::string> parts;
+       if (!precheckElement("animated_image", element, 6, 7, parts))
                return;
-       }
 
        std::vector<std::string> v_pos  = split(parts[0], ',');
        std::vector<std::string> v_geom = split(parts[1], ',');
@@ -944,218 +932,205 @@ void GUIFormSpecMenu::parseAnimatedImage(parserData *data, const std::string &el
 
 void GUIFormSpecMenu::parseItemImage(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("item_image", element, 3, 3, parts))
+               return;
 
-       if ((parts.size() == 3) ||
-               ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string name = parts[2];
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string name = parts[2];
 
-               MY_CHECKPOS("itemimage",0);
-               MY_CHECKGEOM("itemimage",1);
+       MY_CHECKPOS("item_image",0);
+       MY_CHECKGEOM("item_image",1);
 
-               v2s32 pos;
-               v2s32 geom;
+       v2s32 pos;
+       v2s32 geom;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       geom.X = stof(v_geom[0]) * (float)imgsize.X;
-                       geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
-               }
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               geom.X = stof(v_geom[0]) * (float)imgsize.X;
+               geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
+       }
 
-               if(!data->explicit_size)
-                       warningstream<<"invalid use of item_image without a size[] element"<<std::endl;
+       if(!data->explicit_size)
+               warningstream<<"invalid use of item_image without a size[] element"<<std::endl;
 
-               FieldSpec spec(
-                       "",
-                       L"",
-                       L"",
-                       258 + m_fields.size(),
-                       2
-               );
-               spec.ftype = f_ItemImage;
+       FieldSpec spec(
+               "",
+               L"",
+               L"",
+               258 + m_fields.size(),
+               2
+       );
+       spec.ftype = f_ItemImage;
 
-               GUIItemImage *e = new GUIItemImage(Environment, data->current_parent, spec.fid,
-                               core::rect<s32>(pos, pos + geom), name, m_font, m_client);
-               auto style = getDefaultStyleForElement("item_image", spec.fname);
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       GUIItemImage *e = new GUIItemImage(Environment, data->current_parent, spec.fid,
+                       core::rect<s32>(pos, pos + geom), name, m_font, m_client);
+       auto style = getDefaultStyleForElement("item_image", spec.fname);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
 
-               // item images should let events through
-               m_clickthrough_elements.push_back(e);
+       // item images should let events through
+       m_clickthrough_elements.push_back(e);
 
-               m_fields.push_back(spec);
-               return;
-       }
-       errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element,
                const std::string &type)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("button", element, 4, 4, parts))
+               return;
 
-       if ((parts.size() == 4) ||
-               ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string name = parts[2];
-               std::string label = parts[3];
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string name = parts[2];
+       std::string label = parts[3];
 
-               MY_CHECKPOS("button",0);
-               MY_CHECKGEOM("button",1);
+       MY_CHECKPOS("button",0);
+       MY_CHECKGEOM("button",1);
 
-               v2s32 pos;
-               v2s32 geom;
-               core::rect<s32> rect;
+       v2s32 pos;
+       v2s32 geom;
+       core::rect<s32> rect;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-                       rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
-                               pos.Y+geom.Y);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
-                       pos.Y += (stof(v_geom[1]) * (float)imgsize.Y)/2;
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+               rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
+                       pos.Y+geom.Y);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
+               pos.Y += (stof(v_geom[1]) * (float)imgsize.Y)/2;
 
-                       rect = core::rect<s32>(pos.X, pos.Y - m_btn_height,
-                                               pos.X + geom.X, pos.Y + m_btn_height);
-               }
+               rect = core::rect<s32>(pos.X, pos.Y - m_btn_height,
+                                       pos.X + geom.X, pos.Y + m_btn_height);
+       }
 
-               if(!data->explicit_size)
-                       warningstream<<"invalid use of button without a size[] element"<<std::endl;
+       if(!data->explicit_size)
+               warningstream<<"invalid use of button without a size[] element"<<std::endl;
 
-               std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label)));
+       std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label)));
 
-               FieldSpec spec(
-                       name,
-                       wlabel,
-                       L"",
-                       258 + m_fields.size()
-               );
-               spec.ftype = f_Button;
-               if(type == "button_exit")
-                       spec.is_exit = true;
-
-               GUIButton *e = GUIButton::addButton(Environment, rect, m_tsrc,
-                               data->current_parent, spec.fid, spec.flabel.c_str());
+       FieldSpec spec(
+               name,
+               wlabel,
+               L"",
+               258 + m_fields.size()
+       );
+       spec.ftype = f_Button;
+       if(type == "button_exit")
+               spec.is_exit = true;
 
-               auto style = getStyleForElement(type, name, (type != "button") ? "button" : "");
+       GUIButton *e = GUIButton::addButton(Environment, rect, m_tsrc,
+                       data->current_parent, spec.fid, spec.flabel.c_str());
 
-               spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, "");
+       auto style = getStyleForElement(type, name, (type != "button") ? "button" : "");
 
-               e->setStyles(style);
+       spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, "");
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       e->setStyles(style);
 
-               m_fields.push_back(spec);
-               return;
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
        }
-       errorstream<< "Invalid button element(" << parts.size() << "): '" << element << "'"  << std::endl;
+
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseBackground(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("background", element, 3, 5, parts))
+               return;
 
-       if ((parts.size() >= 3 && parts.size() <= 5) ||
-                       (parts.size() > 5 && m_formspec_version > FORMSPEC_API_VERSION)) {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string name = unescape_string(parts[2]);
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string name = unescape_string(parts[2]);
 
-               MY_CHECKPOS("background",0);
-               MY_CHECKGEOM("background",1);
+       MY_CHECKPOS("background",0);
+       MY_CHECKGEOM("background",1);
 
-               v2s32 pos;
-               v2s32 geom;
+       v2s32 pos;
+       v2s32 geom;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       pos.X -= (spacing.X - (float)imgsize.X) / 2;
-                       pos.Y -= (spacing.Y - (float)imgsize.Y) / 2;
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               pos.X -= (spacing.X - (float)imgsize.X) / 2;
+               pos.Y -= (spacing.Y - (float)imgsize.Y) / 2;
 
-                       geom.X = stof(v_geom[0]) * spacing.X;
-                       geom.Y = stof(v_geom[1]) * spacing.Y;
-               }
+               geom.X = stof(v_geom[0]) * spacing.X;
+               geom.Y = stof(v_geom[1]) * spacing.Y;
+       }
 
-               bool clip = false;
-               if (parts.size() >= 4 && is_yes(parts[3])) {
-                       if (data->real_coordinates) {
-                               pos = getRealCoordinateBasePos(v_pos) * -1;
-                               geom = v2s32(0, 0);
-                       } else {
-                               pos.X = stoi(v_pos[0]); //acts as offset
-                               pos.Y = stoi(v_pos[1]);
-                       }
-                       clip = true;
+       bool clip = false;
+       if (parts.size() >= 4 && is_yes(parts[3])) {
+               if (data->real_coordinates) {
+                       pos = getRealCoordinateBasePos(v_pos) * -1;
+                       geom = v2s32(0, 0);
+               } else {
+                       pos.X = stoi(v_pos[0]); //acts as offset
+                       pos.Y = stoi(v_pos[1]);
                }
+               clip = true;
+       }
 
-               core::rect<s32> middle;
-               if (parts.size() >= 5) {
-                       std::vector<std::string> v_middle = split(parts[4], ',');
-                       if (v_middle.size() == 1) {
-                               s32 x = stoi(v_middle[0]);
-                               middle.UpperLeftCorner = core::vector2di(x, x);
-                               middle.LowerRightCorner = core::vector2di(-x, -x);
-                       } else if (v_middle.size() == 2) {
-                               s32 x = stoi(v_middle[0]);
-                               s32 y = stoi(v_middle[1]);
-                               middle.UpperLeftCorner = core::vector2di(x, y);
-                               middle.LowerRightCorner = core::vector2di(-x, -y);
-                               // `-x` is interpreted as `w - x`
-                       } else if (v_middle.size() == 4) {
-                               middle.UpperLeftCorner = core::vector2di(stoi(v_middle[0]), stoi(v_middle[1]));
-                               middle.LowerRightCorner = core::vector2di(stoi(v_middle[2]), stoi(v_middle[3]));
-                       } else {
-                               warningstream << "Invalid rectangle given to middle param of background[] element" << std::endl;
-                       }
+       core::rect<s32> middle;
+       if (parts.size() >= 5) {
+               std::vector<std::string> v_middle = split(parts[4], ',');
+               if (v_middle.size() == 1) {
+                       s32 x = stoi(v_middle[0]);
+                       middle.UpperLeftCorner = core::vector2di(x, x);
+                       middle.LowerRightCorner = core::vector2di(-x, -x);
+               } else if (v_middle.size() == 2) {
+                       s32 x = stoi(v_middle[0]);
+                       s32 y = stoi(v_middle[1]);
+                       middle.UpperLeftCorner = core::vector2di(x, y);
+                       middle.LowerRightCorner = core::vector2di(-x, -y);
+                       // `-x` is interpreted as `w - x`
+               } else if (v_middle.size() == 4) {
+                       middle.UpperLeftCorner = core::vector2di(stoi(v_middle[0]), stoi(v_middle[1]));
+                       middle.LowerRightCorner = core::vector2di(stoi(v_middle[2]), stoi(v_middle[3]));
+               } else {
+                       warningstream << "Invalid rectangle given to middle param of background[] element" << std::endl;
                }
+       }
 
-               if (!data->explicit_size && !clip)
-                       warningstream << "invalid use of unclipped background without a size[] element" << std::endl;
+       if (!data->explicit_size && !clip)
+               warningstream << "invalid use of unclipped background without a size[] element" << std::endl;
 
-               FieldSpec spec(
-                       name,
-                       L"",
-                       L"",
-                       258 + m_fields.size()
-               );
-
-               core::rect<s32> rect;
-               if (!clip) {
-                       // no auto_clip => position like normal image
-                       rect = core::rect<s32>(pos, pos + geom);
-               } else {
-                       // it will be auto-clipped when drawing
-                       rect = core::rect<s32>(-pos, pos);
-               }
+       FieldSpec spec(
+               name,
+               L"",
+               L"",
+               258 + m_fields.size()
+       );
 
-               GUIBackgroundImage *e = new GUIBackgroundImage(Environment, this, spec.fid,
-                               rect, name, middle, m_tsrc, clip);
+       core::rect<s32> rect;
+       if (!clip) {
+               // no auto_clip => position like normal image
+               rect = core::rect<s32>(pos, pos + geom);
+       } else {
+               // it will be auto-clipped when drawing
+               rect = core::rect<s32>(-pos, pos);
+       }
 
-               FATAL_ERROR_IF(!e, "Failed to create background formspec element");
+       GUIBackgroundImage *e = new GUIBackgroundImage(Environment, data->background_parent.get(),
+                       spec.fid, rect, name, middle, m_tsrc, clip);
 
-               e->setNotClipped(true);
+       FATAL_ERROR_IF(!e, "Failed to create background formspec element");
 
-               e->setVisible(false); // the element is drawn manually before all others
+       e->setNotClipped(true);
 
-               m_backgrounds.push_back(e);
-               m_fields.push_back(spec);
-               return;
-       }
-       errorstream<< "Invalid background element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       m_fields.push_back(spec);
+       e->drop();
 }
 
 void GUIFormSpecMenu::parseTableOptions(parserData* data, const std::string &element)
@@ -1192,338 +1167,320 @@ void GUIFormSpecMenu::parseTableColumns(parserData* data, const std::string &ele
 
 void GUIFormSpecMenu::parseTable(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("table", element, 4, 5, parts))
+               return;
 
-       if (((parts.size() == 4) || (parts.size() == 5)) ||
-               ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string name = parts[2];
-               std::vector<std::string> items = split(parts[3],',');
-               std::string str_initial_selection;
-               std::string str_transparent = "false";
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string name = parts[2];
+       std::vector<std::string> items = split(parts[3],',');
+       std::string str_initial_selection;
+       std::string str_transparent = "false";
 
-               if (parts.size() >= 5)
-                       str_initial_selection = parts[4];
+       if (parts.size() >= 5)
+               str_initial_selection = parts[4];
 
-               MY_CHECKPOS("table",0);
-               MY_CHECKGEOM("table",1);
+       MY_CHECKPOS("table",0);
+       MY_CHECKGEOM("table",1);
 
-               v2s32 pos;
-               v2s32 geom;
+       v2s32 pos;
+       v2s32 geom;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       geom.X = stof(v_geom[0]) * spacing.X;
-                       geom.Y = stof(v_geom[1]) * spacing.Y;
-               }
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               geom.X = stof(v_geom[0]) * spacing.X;
+               geom.Y = stof(v_geom[1]) * spacing.Y;
+       }
 
-               core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
+       core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
 
-               FieldSpec spec(
-                       name,
-                       L"",
-                       L"",
-                       258 + m_fields.size()
-               );
+       FieldSpec spec(
+               name,
+               L"",
+               L"",
+               258 + m_fields.size()
+       );
 
-               spec.ftype = f_Table;
+       spec.ftype = f_Table;
 
-               for (std::string &item : items) {
-                       item = wide_to_utf8(unescape_translate(utf8_to_wide(unescape_string(item))));
-               }
+       for (std::string &item : items) {
+               item = wide_to_utf8(unescape_translate(utf8_to_wide(unescape_string(item))));
+       }
 
-               //now really show table
-               GUITable *e = new GUITable(Environment, data->current_parent, spec.fid,
-                               rect, m_tsrc);
+       //now really show table
+       GUITable *e = new GUITable(Environment, data->current_parent, spec.fid,
+                       rect, m_tsrc);
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
+       }
 
-               e->setTable(data->table_options, data->table_columns, items);
+       e->setTable(data->table_options, data->table_columns, items);
 
-               if (data->table_dyndata.find(name) != data->table_dyndata.end()) {
-                       e->setDynamicData(data->table_dyndata[name]);
-               }
+       if (data->table_dyndata.find(name) != data->table_dyndata.end()) {
+               e->setDynamicData(data->table_dyndata[name]);
+       }
 
-               if (!str_initial_selection.empty() && str_initial_selection != "0")
-                       e->setSelected(stoi(str_initial_selection));
+       if (!str_initial_selection.empty() && str_initial_selection != "0")
+               e->setSelected(stoi(str_initial_selection));
 
-               auto style = getDefaultStyleForElement("table", name);
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
-               e->setOverrideFont(style.getFont());
+       auto style = getDefaultStyleForElement("table", name);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       e->setOverrideFont(style.getFont());
 
-               m_tables.emplace_back(spec, e);
-               m_fields.push_back(spec);
-               return;
-       }
-       errorstream<< "Invalid table element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       m_tables.emplace_back(spec, e);
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseTextList(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("textlist", element, 4, 6, parts))
+               return;
 
-       if (((parts.size() == 4) || (parts.size() == 5) || (parts.size() == 6)) ||
-               ((parts.size() > 6) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string name = parts[2];
-               std::vector<std::string> items = split(parts[3],',');
-               std::string str_initial_selection;
-               std::string str_transparent = "false";
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string name = parts[2];
+       std::vector<std::string> items = split(parts[3],',');
+       std::string str_initial_selection;
+       std::string str_transparent = "false";
 
-               if (parts.size() >= 5)
-                       str_initial_selection = parts[4];
+       if (parts.size() >= 5)
+               str_initial_selection = parts[4];
 
-               if (parts.size() >= 6)
-                       str_transparent = parts[5];
+       if (parts.size() >= 6)
+               str_transparent = parts[5];
 
-               MY_CHECKPOS("textlist",0);
-               MY_CHECKGEOM("textlist",1);
+       MY_CHECKPOS("textlist",0);
+       MY_CHECKGEOM("textlist",1);
 
-               v2s32 pos;
-               v2s32 geom;
+       v2s32 pos;
+       v2s32 geom;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       geom.X = stof(v_geom[0]) * spacing.X;
-                       geom.Y = stof(v_geom[1]) * spacing.Y;
-               }
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               geom.X = stof(v_geom[0]) * spacing.X;
+               geom.Y = stof(v_geom[1]) * spacing.Y;
+       }
 
-               core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
+       core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
 
-               FieldSpec spec(
-                       name,
-                       L"",
-                       L"",
-                       258 + m_fields.size()
-               );
+       FieldSpec spec(
+               name,
+               L"",
+               L"",
+               258 + m_fields.size()
+       );
 
-               spec.ftype = f_Table;
+       spec.ftype = f_Table;
 
-               for (std::string &item : items) {
-                       item = wide_to_utf8(unescape_translate(utf8_to_wide(unescape_string(item))));
-               }
+       for (std::string &item : items) {
+               item = wide_to_utf8(unescape_translate(utf8_to_wide(unescape_string(item))));
+       }
 
-               //now really show list
-               GUITable *e = new GUITable(Environment, data->current_parent, spec.fid,
-                               rect, m_tsrc);
+       //now really show list
+       GUITable *e = new GUITable(Environment, data->current_parent, spec.fid,
+                       rect, m_tsrc);
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
+       }
 
-               e->setTextList(items, is_yes(str_transparent));
+       e->setTextList(items, is_yes(str_transparent));
 
-               if (data->table_dyndata.find(name) != data->table_dyndata.end()) {
-                       e->setDynamicData(data->table_dyndata[name]);
-               }
+       if (data->table_dyndata.find(name) != data->table_dyndata.end()) {
+               e->setDynamicData(data->table_dyndata[name]);
+       }
 
-               if (!str_initial_selection.empty() && str_initial_selection != "0")
-                       e->setSelected(stoi(str_initial_selection));
+       if (!str_initial_selection.empty() && str_initial_selection != "0")
+               e->setSelected(stoi(str_initial_selection));
 
-               auto style = getDefaultStyleForElement("textlist", name);
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
-               e->setOverrideFont(style.getFont());
+       auto style = getDefaultStyleForElement("textlist", name);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       e->setOverrideFont(style.getFont());
 
-               m_tables.emplace_back(spec, e);
-               m_fields.push_back(spec);
-               return;
-       }
-       errorstream<< "Invalid textlist element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       m_tables.emplace_back(spec, e);
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseDropDown(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
-
-       if (parts.size() == 5 || parts.size() == 6 ||
-               (parts.size() > 6 && m_formspec_version > FORMSPEC_API_VERSION))
-       {
-               std::vector<std::string> v_pos = split(parts[0], ',');
-               std::string name = parts[2];
-               std::vector<std::string> items = split(parts[3], ',');
-               std::string str_initial_selection = parts[4];
+       std::vector<std::string> parts;
+       if (!precheckElement("dropdown", element, 5, 6, parts))
+               return;
 
-               if (parts.size() >= 6 && is_yes(parts[5]))
-                       m_dropdown_index_event[name] = true;
+       std::vector<std::string> v_pos = split(parts[0], ',');
+       std::string name = parts[2];
+       std::vector<std::string> items = split(parts[3], ',');
+       std::string str_initial_selection = parts[4];
 
-               MY_CHECKPOS("dropdown",0);
+       if (parts.size() >= 6 && is_yes(parts[5]))
+               m_dropdown_index_event[name] = true;
 
-               v2s32 pos;
-               v2s32 geom;
-               core::rect<s32> rect;
+       MY_CHECKPOS("dropdown",0);
 
-               if (data->real_coordinates) {
-                       std::vector<std::string> v_geom = split(parts[1],',');
+       v2s32 pos;
+       v2s32 geom;
+       core::rect<s32> rect;
 
-                       if (v_geom.size() == 1)
-                               v_geom.emplace_back("1");
+       if (data->real_coordinates) {
+               std::vector<std::string> v_geom = split(parts[1],',');
 
-                       MY_CHECKGEOM("dropdown",1);
+               if (v_geom.size() == 1)
+                       v_geom.emplace_back("1");
 
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-                       rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
-               } else {
-                       pos = getElementBasePos(&v_pos);
+               MY_CHECKGEOM("dropdown",1);
 
-                       s32 width = stof(parts[1]) * spacing.Y;
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+               rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
+       } else {
+               pos = getElementBasePos(&v_pos);
 
-                       rect = core::rect<s32>(pos.X, pos.Y,
-                                       pos.X + width, pos.Y + (m_btn_height * 2));
-               }
+               s32 width = stof(parts[1]) * spacing.Y;
 
-               FieldSpec spec(
-                       name,
-                       L"",
-                       L"",
-                       258 + m_fields.size()
-               );
+               rect = core::rect<s32>(pos.X, pos.Y,
+                               pos.X + width, pos.Y + (m_btn_height * 2));
+       }
 
-               spec.ftype = f_DropDown;
-               spec.send = true;
+       FieldSpec spec(
+               name,
+               L"",
+               L"",
+               258 + m_fields.size()
+       );
 
-               //now really show list
-               gui::IGUIComboBox *e = Environment->addComboBox(rect, data->current_parent,
-                               spec.fid);
+       spec.ftype = f_DropDown;
+       spec.send = true;
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       //now really show list
+       gui::IGUIComboBox *e = Environment->addComboBox(rect, data->current_parent,
+                       spec.fid);
 
-               for (const std::string &item : items) {
-                       e->addItem(unescape_translate(unescape_string(
-                               utf8_to_wide(item))).c_str());
-               }
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
+       }
 
-               if (!str_initial_selection.empty())
-                       e->setSelected(stoi(str_initial_selection)-1);
+       for (const std::string &item : items) {
+               e->addItem(unescape_translate(unescape_string(
+                       utf8_to_wide(item))).c_str());
+       }
 
-               auto style = getDefaultStyleForElement("dropdown", name);
+       if (!str_initial_selection.empty())
+               e->setSelected(stoi(str_initial_selection)-1);
 
-               spec.sound = style.get(StyleSpec::Property::SOUND, "");
+       auto style = getDefaultStyleForElement("dropdown", name);
 
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       spec.sound = style.get(StyleSpec::Property::SOUND, "");
 
-               m_fields.push_back(spec);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
 
-               m_dropdowns.emplace_back(spec, std::vector<std::string>());
-               std::vector<std::string> &values = m_dropdowns.back().second;
-               for (const std::string &item : items) {
-                       values.push_back(unescape_string(item));
-               }
+       m_fields.push_back(spec);
 
-               return;
+       m_dropdowns.emplace_back(spec, std::vector<std::string>());
+       std::vector<std::string> &values = m_dropdowns.back().second;
+       for (const std::string &item : items) {
+               values.push_back(unescape_string(item));
        }
-       errorstream << "Invalid dropdown element(" << parts.size() << "): '" << element
-               << "'" << std::endl;
 }
 
 void GUIFormSpecMenu::parseFieldCloseOnEnter(parserData *data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
-       if (parts.size() == 2 ||
-                       (parts.size() > 2 && m_formspec_version > FORMSPEC_API_VERSION)) {
-               field_close_on_enter[parts[0]] = is_yes(parts[1]);
-       }
+       std::vector<std::string> parts;
+       if (!precheckElement("field_close_on_enter", element, 2, 2, parts))
+               return;
+
+       field_close_on_enter[parts[0]] = is_yes(parts[1]);
 }
 
 void GUIFormSpecMenu::parsePwdField(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
-
-       if (parts.size() == 4 ||
-               (parts.size() > 4 && m_formspec_version > FORMSPEC_API_VERSION))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string name = parts[2];
-               std::string label = parts[3];
-
-               MY_CHECKPOS("pwdfield",0);
-               MY_CHECKGEOM("pwdfield",1);
+       std::vector<std::string> parts;
+       if (!precheckElement("pwdfield", element, 4, 4, parts))
+               return;
 
-               v2s32 pos;
-               v2s32 geom;
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string name = parts[2];
+       std::string label = parts[3];
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       pos -= padding;
+       MY_CHECKPOS("pwdfield",0);
+       MY_CHECKGEOM("pwdfield",1);
 
-                       geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
+       v2s32 pos;
+       v2s32 geom;
 
-                       pos.Y += (stof(v_geom[1]) * (float)imgsize.Y)/2;
-                       pos.Y -= m_btn_height;
-                       geom.Y = m_btn_height*2;
-               }
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               pos -= padding;
 
-               core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
+               geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
 
-               std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label)));
+               pos.Y += (stof(v_geom[1]) * (float)imgsize.Y)/2;
+               pos.Y -= m_btn_height;
+               geom.Y = m_btn_height*2;
+       }
 
-               FieldSpec spec(
-                       name,
-                       wlabel,
-                       L"",
-                       258 + m_fields.size(),
-                       0,
-                       ECI_IBEAM
-                       );
+       core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
 
-               spec.send = true;
-               gui::IGUIEditBox *e = Environment->addEditBox(0, rect, true,
-                               data->current_parent, spec.fid);
+       std::wstring wlabel = translate_string(utf8_to_wide(unescape_string(label)));
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       FieldSpec spec(
+               name,
+               wlabel,
+               L"",
+               258 + m_fields.size(),
+               0,
+               ECI_IBEAM
+               );
 
-               if (label.length() >= 1) {
-                       int font_height = g_fontengine->getTextHeight();
-                       rect.UpperLeftCorner.Y -= font_height;
-                       rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
-                       gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true,
-                               data->current_parent, 0);
-               }
+       spec.send = true;
+       gui::IGUIEditBox *e = Environment->addEditBox(0, rect, true,
+                       data->current_parent, spec.fid);
 
-               e->setPasswordBox(true,L'*');
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
+       }
 
-               auto style = getDefaultStyleForElement("pwdfield", name, "field");
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
-               e->setDrawBorder(style.getBool(StyleSpec::BORDER, true));
-               e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
-               e->setOverrideFont(style.getFont());
+       if (label.length() >= 1) {
+               int font_height = g_fontengine->getTextHeight();
+               rect.UpperLeftCorner.Y -= font_height;
+               rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
+               gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true,
+                       data->current_parent, 0);
+       }
 
-               irr::SEvent evt;
-               evt.EventType            = EET_KEY_INPUT_EVENT;
-               evt.KeyInput.Key         = KEY_END;
-               evt.KeyInput.Char        = 0;
-               evt.KeyInput.Control     = false;
-               evt.KeyInput.Shift       = false;
-               evt.KeyInput.PressedDown = true;
-               e->OnEvent(evt);
+       e->setPasswordBox(true,L'*');
 
-               // Note: Before 5.2.0 "parts.size() >= 5" resulted in a
-               // warning referring to field_close_on_enter[]!
+       auto style = getDefaultStyleForElement("pwdfield", name, "field");
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       e->setDrawBorder(style.getBool(StyleSpec::BORDER, true));
+       e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
+       e->setOverrideFont(style.getFont());
+
+       irr::SEvent evt;
+       evt.EventType            = EET_KEY_INPUT_EVENT;
+       evt.KeyInput.Key         = KEY_END;
+       evt.KeyInput.Char        = 0;
+       evt.KeyInput.Control     = false;
+       evt.KeyInput.Shift       = false;
+       evt.KeyInput.PressedDown = true;
+       e->OnEvent(evt);
+
+       // Note: Before 5.2.0 "parts.size() >= 5" resulted in a
+       // warning referring to field_close_on_enter[]!
 
-               m_fields.push_back(spec);
-               return;
-       }
-       errorstream<< "Invalid pwdfield element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::createTextField(parserData *data, FieldSpec &spec,
@@ -1710,30 +1667,26 @@ void GUIFormSpecMenu::parseTextArea(parserData* data, std::vector<std::string>&
 void GUIFormSpecMenu::parseField(parserData* data, const std::string &element,
                const std::string &type)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement(type, element, 3, 5, parts))
+               return;
 
        if (parts.size() == 3 || parts.size() == 4) {
-               parseSimpleField(data,parts);
+               parseSimpleField(data, parts);
                return;
        }
 
-       if ((parts.size() == 5) ||
-               ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               parseTextArea(data,parts,type);
-               return;
-       }
-       errorstream<< "Invalid field element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       // Else: >= 5 arguments in "parts"
+       parseTextArea(data, parts, type);
 }
 
 void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
+       MY_CHECKCLIENT("list");
 
-       if (parts.size() != 4 && m_formspec_version < FORMSPEC_API_VERSION) {
-               errorstream << "Invalid text element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       std::vector<std::string> parts;
+       if (!precheckElement("hypertext", element, 4, 4, parts))
                return;
-       }
 
        std::vector<std::string> v_pos = split(parts[0], ',');
        std::vector<std::string> v_geom = split(parts[1], ',');
@@ -1784,539 +1737,521 @@ void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &elemen
 
 void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("label", element, 2, 2, parts))
+               return;
 
-       if ((parts.size() == 2) ||
-               ((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::string text = parts[1];
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::string text = parts[1];
 
-               MY_CHECKPOS("label",0);
+       MY_CHECKPOS("label",0);
 
-               if(!data->explicit_size)
-                       warningstream<<"invalid use of label without a size[] element"<<std::endl;
+       if(!data->explicit_size)
+               warningstream<<"invalid use of label without a size[] element"<<std::endl;
 
-               std::vector<std::string> lines = split(text, '\n');
+       std::vector<std::string> lines = split(text, '\n');
 
-               auto style = getDefaultStyleForElement("label", "");
-               gui::IGUIFont *font = style.getFont();
-               if (!font)
-                       font = m_font;
+       auto style = getDefaultStyleForElement("label", "");
+       gui::IGUIFont *font = style.getFont();
+       if (!font)
+               font = m_font;
 
-               for (unsigned int i = 0; i != lines.size(); i++) {
-                       std::wstring wlabel_colors = translate_string(
-                               utf8_to_wide(unescape_string(lines[i])));
-                       // Without color escapes to get the font dimensions
-                       std::wstring wlabel_plain = unescape_enriched(wlabel_colors);
+       for (unsigned int i = 0; i != lines.size(); i++) {
+               std::wstring wlabel_colors = translate_string(
+                       utf8_to_wide(unescape_string(lines[i])));
+               // Without color escapes to get the font dimensions
+               std::wstring wlabel_plain = unescape_enriched(wlabel_colors);
 
-                       core::rect<s32> rect;
+               core::rect<s32> rect;
 
-                       if (data->real_coordinates) {
-                               // Lines are spaced at the distance of 1/2 imgsize.
-                               // This alows lines that line up with the new elements
-                               // easily without sacrificing good line distance.  If
-                               // it was one whole imgsize, it would have too much
-                               // spacing.
-                               v2s32 pos = getRealCoordinateBasePos(v_pos);
+               if (data->real_coordinates) {
+                       // Lines are spaced at the distance of 1/2 imgsize.
+                       // This alows lines that line up with the new elements
+                       // easily without sacrificing good line distance.  If
+                       // it was one whole imgsize, it would have too much
+                       // spacing.
+                       v2s32 pos = getRealCoordinateBasePos(v_pos);
 
-                               // Labels are positioned by their center, not their top.
-                               pos.Y += (((float) imgsize.Y) / -2) + (((float) imgsize.Y) * i / 2);
+                       // Labels are positioned by their center, not their top.
+                       pos.Y += (((float) imgsize.Y) / -2) + (((float) imgsize.Y) * i / 2);
 
-                               rect = core::rect<s32>(
-                                       pos.X, pos.Y,
-                                       pos.X + font->getDimension(wlabel_plain.c_str()).Width,
-                                       pos.Y + imgsize.Y);
+                       rect = core::rect<s32>(
+                               pos.X, pos.Y,
+                               pos.X + font->getDimension(wlabel_plain.c_str()).Width,
+                               pos.Y + imgsize.Y);
 
-                       } else {
-                               // Lines are spaced at the nominal distance of
-                               // 2/5 inventory slot, even if the font doesn't
-                               // quite match that.  This provides consistent
-                               // form layout, at the expense of sometimes
-                               // having sub-optimal spacing for the font.
-                               // We multiply by 2 and then divide by 5, rather
-                               // than multiply by 0.4, to get exact results
-                               // in the integer cases: 0.4 is not exactly
-                               // representable in binary floating point.
-
-                               v2s32 pos = getElementBasePos(nullptr);
-                               pos.X += stof(v_pos[0]) * spacing.X;
-                               pos.Y += (stof(v_pos[1]) + 7.0f / 30.0f) * spacing.Y;
-
-                               pos.Y += ((float) i) * spacing.Y * 2.0 / 5.0;
-
-                               rect = core::rect<s32>(
-                                       pos.X, pos.Y - m_btn_height,
-                                       pos.X + font->getDimension(wlabel_plain.c_str()).Width,
-                                       pos.Y + m_btn_height);
-                       }
+               } else {
+                       // Lines are spaced at the nominal distance of
+                       // 2/5 inventory slot, even if the font doesn't
+                       // quite match that.  This provides consistent
+                       // form layout, at the expense of sometimes
+                       // having sub-optimal spacing for the font.
+                       // We multiply by 2 and then divide by 5, rather
+                       // than multiply by 0.4, to get exact results
+                       // in the integer cases: 0.4 is not exactly
+                       // representable in binary floating point.
+
+                       v2s32 pos = getElementBasePos(nullptr);
+                       pos.X += stof(v_pos[0]) * spacing.X;
+                       pos.Y += (stof(v_pos[1]) + 7.0f / 30.0f) * spacing.Y;
+
+                       pos.Y += ((float) i) * spacing.Y * 2.0 / 5.0;
 
-                       FieldSpec spec(
-                               "",
-                               wlabel_colors,
-                               L"",
-                               258 + m_fields.size(),
-                               4
-                       );
-                       gui::IGUIStaticText *e = gui::StaticText::add(Environment,
-                                       spec.flabel.c_str(), rect, false, false, data->current_parent,
-                                       spec.fid);
-                       e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
+                       rect = core::rect<s32>(
+                               pos.X, pos.Y - m_btn_height,
+                               pos.X + font->getDimension(wlabel_plain.c_str()).Width,
+                               pos.Y + m_btn_height);
+               }
 
-                       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
-                       e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
-                       e->setOverrideFont(font);
+               FieldSpec spec(
+                       "",
+                       wlabel_colors,
+                       L"",
+                       258 + m_fields.size(),
+                       4
+               );
+               gui::IGUIStaticText *e = gui::StaticText::add(Environment,
+                               spec.flabel.c_str(), rect, false, false, data->current_parent,
+                               spec.fid);
+               e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
 
-                       m_fields.push_back(spec);
+               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+               e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
+               e->setOverrideFont(font);
 
-                       // labels should let events through
-                       e->grab();
-                       m_clickthrough_elements.push_back(e);
-               }
+               m_fields.push_back(spec);
 
-               return;
+               // labels should let events through
+               e->grab();
+               m_clickthrough_elements.push_back(e);
        }
-       errorstream << "Invalid label element(" << parts.size() << "): '" << element
-               << "'"  << std::endl;
 }
 
 void GUIFormSpecMenu::parseVertLabel(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("vertlabel", element, 2, 2, parts))
+               return;
 
-       if ((parts.size() == 2) ||
-               ((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::wstring text = unescape_translate(
-                       unescape_string(utf8_to_wide(parts[1])));
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::wstring text = unescape_translate(
+               unescape_string(utf8_to_wide(parts[1])));
 
-               MY_CHECKPOS("vertlabel",1);
+       MY_CHECKPOS("vertlabel",1);
 
-               auto style = getDefaultStyleForElement("vertlabel", "", "label");
-               gui::IGUIFont *font = style.getFont();
-               if (!font)
-                       font = m_font;
+       auto style = getDefaultStyleForElement("vertlabel", "", "label");
+       gui::IGUIFont *font = style.getFont();
+       if (!font)
+               font = m_font;
 
-               v2s32 pos;
-               core::rect<s32> rect;
+       v2s32 pos;
+       core::rect<s32> rect;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
 
-                       // Vertlabels are positioned by center, not left.
-                       pos.X -= imgsize.X / 2;
+               // Vertlabels are positioned by center, not left.
+               pos.X -= imgsize.X / 2;
 
-                       // We use text.length + 1 because without it, the rect
-                       // isn't quite tall enough and cuts off the text.
-                       rect = core::rect<s32>(pos.X, pos.Y,
-                               pos.X + imgsize.X,
-                               pos.Y + font_line_height(font) *
-                               (text.length() + 1));
+               // We use text.length + 1 because without it, the rect
+               // isn't quite tall enough and cuts off the text.
+               rect = core::rect<s32>(pos.X, pos.Y,
+                       pos.X + imgsize.X,
+                       pos.Y + font_line_height(font) *
+                       (text.length() + 1));
 
-               } else {
-                       pos = getElementBasePos(&v_pos);
+       } else {
+               pos = getElementBasePos(&v_pos);
 
-                       // As above, the length must be one longer. The width of
-                       // the rect (15 pixels) seems rather arbitrary, but
-                       // changing it might break something.
-                       rect = core::rect<s32>(
-                               pos.X, pos.Y+((imgsize.Y/2) - m_btn_height),
-                               pos.X+15, pos.Y +
-                                       font_line_height(font) *
-                                       (text.length() + 1) +
-                                       ((imgsize.Y/2) - m_btn_height));
-               }
+               // As above, the length must be one longer. The width of
+               // the rect (15 pixels) seems rather arbitrary, but
+               // changing it might break something.
+               rect = core::rect<s32>(
+                       pos.X, pos.Y+((imgsize.Y/2) - m_btn_height),
+                       pos.X+15, pos.Y +
+                               font_line_height(font) *
+                               (text.length() + 1) +
+                               ((imgsize.Y/2) - m_btn_height));
+       }
 
-               if(!data->explicit_size)
-                       warningstream<<"invalid use of label without a size[] element"<<std::endl;
+       if(!data->explicit_size)
+               warningstream<<"invalid use of label without a size[] element"<<std::endl;
 
-               std::wstring label;
+       std::wstring label;
 
-               for (wchar_t i : text) {
-                       label += i;
-                       label += L"\n";
-               }
+       for (wchar_t i : text) {
+               label += i;
+               label += L"\n";
+       }
 
-               FieldSpec spec(
-                       "",
-                       label,
-                       L"",
-                       258 + m_fields.size()
-               );
-               gui::IGUIStaticText *e = gui::StaticText::add(Environment, spec.flabel.c_str(),
-                               rect, false, false, data->current_parent, spec.fid);
-               e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
+       FieldSpec spec(
+               "",
+               label,
+               L"",
+               258 + m_fields.size()
+       );
+       gui::IGUIStaticText *e = gui::StaticText::add(Environment, spec.flabel.c_str(),
+                       rect, false, false, data->current_parent, spec.fid);
+       e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
 
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
-               e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
-               e->setOverrideFont(font);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
+       e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
+       e->setOverrideFont(font);
 
-               m_fields.push_back(spec);
+       m_fields.push_back(spec);
 
-               // vertlabels should let events through
-               e->grab();
-               m_clickthrough_elements.push_back(e);
-               return;
-       }
-       errorstream<< "Invalid vertlabel element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       // vertlabels should let events through
+       e->grab();
+       m_clickthrough_elements.push_back(e);
 }
 
 void GUIFormSpecMenu::parseImageButton(parserData* data, const std::string &element,
                const std::string &type)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("image_button", element, 5, 8, parts))
+               return;
 
-       if ((((parts.size() >= 5) && (parts.size() <= 8)) && (parts.size() != 6)) ||
-               ((parts.size() > 8) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string image_name = parts[2];
-               std::string name = parts[3];
-               std::string label = parts[4];
+       if (parts.size() == 6) {
+               // Invalid argument count.
+               errorstream << "Invalid image_button element(" << parts.size() << "): '" << element << "'" << std::endl;
+               return;
+       }
 
-               MY_CHECKPOS("imagebutton",0);
-               MY_CHECKGEOM("imagebutton",1);
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string image_name = parts[2];
+       std::string name = parts[3];
+       std::string label = parts[4];
 
-               std::string pressed_image_name;
+       MY_CHECKPOS("image_button",0);
+       MY_CHECKGEOM("image_button",1);
 
-               if (parts.size() >= 8) {
-                       pressed_image_name = parts[7];
-               }
+       std::string pressed_image_name;
 
-               v2s32 pos;
-               v2s32 geom;
-
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
-                       geom.Y = (stof(v_geom[1]) * spacing.Y) - (spacing.Y - imgsize.Y);
-               }
+       if (parts.size() >= 8) {
+               pressed_image_name = parts[7];
+       }
 
-               core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
-                       pos.Y+geom.Y);
+       v2s32 pos;
+       v2s32 geom;
 
-               if (!data->explicit_size)
-                       warningstream<<"invalid use of image_button without a size[] element"<<std::endl;
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
+               geom.Y = (stof(v_geom[1]) * spacing.Y) - (spacing.Y - imgsize.Y);
+       }
 
-               image_name = unescape_string(image_name);
-               pressed_image_name = unescape_string(pressed_image_name);
+       core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
+               pos.Y+geom.Y);
 
-               std::wstring wlabel = utf8_to_wide(unescape_string(label));
+       if (!data->explicit_size)
+               warningstream<<"invalid use of image_button without a size[] element"<<std::endl;
 
-               FieldSpec spec(
-                       name,
-                       wlabel,
-                       utf8_to_wide(image_name),
-                       258 + m_fields.size()
-               );
-               spec.ftype = f_Button;
-               if (type == "image_button_exit")
-                       spec.is_exit = true;
+       image_name = unescape_string(image_name);
+       pressed_image_name = unescape_string(pressed_image_name);
 
-               GUIButtonImage *e = GUIButtonImage::addButton(Environment, rect, m_tsrc,
-                               data->current_parent, spec.fid, spec.flabel.c_str());
+       std::wstring wlabel = utf8_to_wide(unescape_string(label));
 
-               if (spec.fname == m_focused_element) {
-                       Environment->setFocus(e);
-               }
+       FieldSpec spec(
+               name,
+               wlabel,
+               utf8_to_wide(image_name),
+               258 + m_fields.size()
+       );
+       spec.ftype = f_Button;
+       if (type == "image_button_exit")
+               spec.is_exit = true;
 
-               auto style = getStyleForElement("image_button", spec.fname);
+       GUIButtonImage *e = GUIButtonImage::addButton(Environment, rect, m_tsrc,
+                       data->current_parent, spec.fid, spec.flabel.c_str());
 
-               spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, "");
+       if (spec.fname == m_focused_element) {
+               Environment->setFocus(e);
+       }
 
-               // Override style properties with values specified directly in the element
-               if (!image_name.empty())
-                       style[StyleSpec::STATE_DEFAULT].set(StyleSpec::FGIMG, image_name);
+       auto style = getStyleForElement("image_button", spec.fname);
 
-               if (!pressed_image_name.empty())
-                       style[StyleSpec::STATE_PRESSED].set(StyleSpec::FGIMG, pressed_image_name);
+       spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, "");
 
-               if (parts.size() >= 7) {
-                       style[StyleSpec::STATE_DEFAULT].set(StyleSpec::NOCLIP, parts[5]);
-                       style[StyleSpec::STATE_DEFAULT].set(StyleSpec::BORDER, parts[6]);
-               }
+       // Override style properties with values specified directly in the element
+       if (!image_name.empty())
+               style[StyleSpec::STATE_DEFAULT].set(StyleSpec::FGIMG, image_name);
 
-               e->setStyles(style);
-               e->setScaleImage(true);
+       if (!pressed_image_name.empty())
+               style[StyleSpec::STATE_PRESSED].set(StyleSpec::FGIMG, pressed_image_name);
 
-               m_fields.push_back(spec);
-               return;
+       if (parts.size() >= 7) {
+               style[StyleSpec::STATE_DEFAULT].set(StyleSpec::NOCLIP, parts[5]);
+               style[StyleSpec::STATE_DEFAULT].set(StyleSpec::BORDER, parts[6]);
        }
 
-       errorstream<< "Invalid imagebutton element(" << parts.size() << "): '" << element << "'"  << std::endl;
+       e->setStyles(style);
+       e->setScaleImage(true);
+
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseTabHeader(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
-
-       if (((parts.size() == 4) || (parts.size() == 6)) || (parts.size() == 7 &&
-               data->real_coordinates) || ((parts.size() > 6) &&
-               (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> parts;
+       if (!precheckElement("tabheader", element, 4, 7, parts))
+               return;
 
-               // If we're using real coordinates, add an extra field for height.
-               // Width is not here because tabs are the width of the text, and
-               // there's no reason to change that.
-               unsigned int i = 0;
-               std::vector<std::string> v_geom = {"1", "1"}; // Dummy width and height
-               bool auto_width = true;
-               if (parts.size() == 7) {
-                       i++;
+       // Length 7: Additional "height" parameter after "pos". Only valid with real_coordinates.
+       // Note: New arguments for the "height" syntax cannot be added without breaking older clients.
+       if (parts.size() == 5 || (parts.size() == 7 && !data->real_coordinates)) {
+               errorstream << "Invalid tabheader element(" << parts.size() << "): '"
+                       << element << "'" << std::endl;
+               return;
+       }
 
-                       v_geom = split(parts[1], ',');
-                       if (v_geom.size() == 1)
-                               v_geom.insert(v_geom.begin(), "1"); // Dummy value
-                       else
-                               auto_width = false;
-               }
+       std::vector<std::string> v_pos = split(parts[0],',');
 
-               std::string name = parts[i+1];
-               std::vector<std::string> buttons = split(parts[i+2], ',');
-               std::string str_index = parts[i+3];
-               bool show_background = true;
-               bool show_border = true;
-               int tab_index = stoi(str_index) - 1;
+       // If we're using real coordinates, add an extra field for height.
+       // Width is not here because tabs are the width of the text, and
+       // there's no reason to change that.
+       unsigned int i = 0;
+       std::vector<std::string> v_geom = {"1", "1"}; // Dummy width and height
+       bool auto_width = true;
+       if (parts.size() == 7) {
+               i++;
+
+               v_geom = split(parts[1], ',');
+               if (v_geom.size() == 1)
+                       v_geom.insert(v_geom.begin(), "1"); // Dummy value
+               else
+                       auto_width = false;
+       }
 
-               MY_CHECKPOS("tabheader", 0);
+       std::string name = parts[i+1];
+       std::vector<std::string> buttons = split(parts[i+2], ',');
+       std::string str_index = parts[i+3];
+       bool show_background = true;
+       bool show_border = true;
+       int tab_index = stoi(str_index) - 1;
 
-               if (parts.size() == 6 + i) {
-                       if (parts[4+i] == "true")
-                               show_background = false;
-                       if (parts[5+i] == "false")
-                               show_border = false;
-               }
+       MY_CHECKPOS("tabheader", 0);
 
-               FieldSpec spec(
-                       name,
-                       L"",
-                       L"",
-                       258 + m_fields.size()
-               );
+       if (parts.size() == 6 + i) {
+               if (parts[4+i] == "true")
+                       show_background = false;
+               if (parts[5+i] == "false")
+                       show_border = false;
+       }
 
-               spec.ftype = f_TabHeader;
+       FieldSpec spec(
+               name,
+               L"",
+               L"",
+               258 + m_fields.size()
+       );
 
-               v2s32 pos;
-               v2s32 geom;
+       spec.ftype = f_TabHeader;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
+       v2s32 pos;
+       v2s32 geom;
 
-                       geom = getRealCoordinateGeometry(v_geom);
-                       // Set default height
-                       if (parts.size() <= 6)
-                               geom.Y = m_btn_height * 2;
-                       pos.Y -= geom.Y; // TabHeader base pos is the bottom, not the top.
-                       if (auto_width)
-                               geom.X = DesiredRect.getWidth(); // Set automatic width
-
-                       MY_CHECKGEOM("tabheader", 1);
-               } else {
-                       v2f32 pos_f = pos_offset * spacing;
-                       pos_f.X += stof(v_pos[0]) * spacing.X;
-                       pos_f.Y += stof(v_pos[1]) * spacing.Y - m_btn_height * 2;
-                       pos = v2s32(pos_f.X, pos_f.Y);
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
 
+               geom = getRealCoordinateGeometry(v_geom);
+               // Set default height
+               if (parts.size() <= 6)
                        geom.Y = m_btn_height * 2;
-                       geom.X = DesiredRect.getWidth();
-               }
+               pos.Y -= geom.Y; // TabHeader base pos is the bottom, not the top.
+               if (auto_width)
+                       geom.X = DesiredRect.getWidth(); // Set automatic width
 
-               core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
-                               pos.Y+geom.Y);
+               MY_CHECKGEOM("tabheader", 1);
+       } else {
+               v2f32 pos_f = pos_offset * spacing;
+               pos_f.X += stof(v_pos[0]) * spacing.X;
+               pos_f.Y += stof(v_pos[1]) * spacing.Y - m_btn_height * 2;
+               pos = v2s32(pos_f.X, pos_f.Y);
 
-               gui::IGUITabControl *e = Environment->addTabControl(rect,
-                               data->current_parent, show_background, show_border, spec.fid);
-               e->setAlignment(irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT,
-                               irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_LOWERRIGHT);
-               e->setTabHeight(geom.Y);
+               geom.Y = m_btn_height * 2;
+               geom.X = DesiredRect.getWidth();
+       }
 
-               auto style = getDefaultStyleForElement("tabheader", name);
+       core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
+                       pos.Y+geom.Y);
 
-               spec.sound = style.get(StyleSpec::Property::SOUND, "");
+       gui::IGUITabControl *e = Environment->addTabControl(rect,
+                       data->current_parent, show_background, show_border, spec.fid);
+       e->setAlignment(irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_UPPERLEFT,
+                       irr::gui::EGUIA_UPPERLEFT, irr::gui::EGUIA_LOWERRIGHT);
+       e->setTabHeight(geom.Y);
 
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, true));
+       auto style = getDefaultStyleForElement("tabheader", name);
 
-               for (const std::string &button : buttons) {
-                       auto tab = e->addTab(unescape_translate(unescape_string(
-                               utf8_to_wide(button))).c_str(), -1);
-                       if (style.isNotDefault(StyleSpec::BGCOLOR))
-                               tab->setBackgroundColor(style.getColor(StyleSpec::BGCOLOR));
+       spec.sound = style.get(StyleSpec::Property::SOUND, "");
 
-                       tab->setTextColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
-               }
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, true));
 
-               if ((tab_index >= 0) &&
-                               (buttons.size() < INT_MAX) &&
-                               (tab_index < (int) buttons.size()))
-                       e->setActiveTab(tab_index);
+       for (const std::string &button : buttons) {
+               auto tab = e->addTab(unescape_translate(unescape_string(
+                       utf8_to_wide(button))).c_str(), -1);
+               if (style.isNotDefault(StyleSpec::BGCOLOR))
+                       tab->setBackgroundColor(style.getColor(StyleSpec::BGCOLOR));
 
-               m_fields.push_back(spec);
-               return;
+               tab->setTextColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
        }
-       errorstream << "Invalid TabHeader element(" << parts.size() << "): '"
-                       << element << "'"  << std::endl;
+
+       if ((tab_index >= 0) &&
+                       (buttons.size() < INT_MAX) &&
+                       (tab_index < (int) buttons.size()))
+               e->setActiveTab(tab_index);
+
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &element)
 {
-       if (m_client == 0) {
-               warningstream << "invalid use of item_image_button with m_client==0"
-                       << std::endl;
-               return;
-       }
-
-       std::vector<std::string> parts = split(element,';');
+       MY_CHECKCLIENT("item_image_button");
 
-       if ((parts.size() == 5) ||
-               ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0],',');
-               std::vector<std::string> v_geom = split(parts[1],',');
-               std::string item_name = parts[2];
-               std::string name = parts[3];
-               std::string label = parts[4];
+       std::vector<std::string> parts;
+       if (!precheckElement("item_image_button", element, 5, 5, parts))
+               return;
 
-               label = unescape_string(label);
-               item_name = unescape_string(item_name);
+       std::vector<std::string> v_pos = split(parts[0],',');
+       std::vector<std::string> v_geom = split(parts[1],',');
+       std::string item_name = parts[2];
+       std::string name = parts[3];
+       std::string label = parts[4];
 
-               MY_CHECKPOS("itemimagebutton",0);
-               MY_CHECKGEOM("itemimagebutton",1);
+       label = unescape_string(label);
+       item_name = unescape_string(item_name);
 
-               v2s32 pos;
-               v2s32 geom;
+       MY_CHECKPOS("item_image_button",0);
+       MY_CHECKGEOM("item_image_button",1);
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
-                       geom.Y = (stof(v_geom[1]) * spacing.Y) - (spacing.Y - imgsize.Y);
-               }
+       v2s32 pos;
+       v2s32 geom;
 
-               core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
+               geom.Y = (stof(v_geom[1]) * spacing.Y) - (spacing.Y - imgsize.Y);
+       }
 
-               if(!data->explicit_size)
-                       warningstream<<"invalid use of item_image_button without a size[] element"<<std::endl;
+       core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
 
-               IItemDefManager *idef = m_client->idef();
-               ItemStack item;
-               item.deSerialize(item_name, idef);
+       if(!data->explicit_size)
+               warningstream<<"invalid use of item_image_button without a size[] element"<<std::endl;
 
-               m_tooltips[name] =
-                       TooltipSpec(utf8_to_wide(item.getDefinition(idef).description),
-                                               m_default_tooltip_bgcolor,
-                                               m_default_tooltip_color);
+       IItemDefManager *idef = m_client->idef();
+       ItemStack item;
+       item.deSerialize(item_name, idef);
 
-               // the spec for the button
-               FieldSpec spec_btn(
-                       name,
-                       utf8_to_wide(label),
-                       utf8_to_wide(item_name),
-                       258 + m_fields.size(),
-                       2
-               );
+       m_tooltips[name] =
+               TooltipSpec(utf8_to_wide(item.getDefinition(idef).description),
+                                       m_default_tooltip_bgcolor,
+                                       m_default_tooltip_color);
 
-               GUIButtonItemImage *e_btn = GUIButtonItemImage::addButton(Environment,
-                               rect, m_tsrc, data->current_parent, spec_btn.fid, spec_btn.flabel.c_str(),
-                               item_name, m_client);
+       // the spec for the button
+       FieldSpec spec_btn(
+               name,
+               utf8_to_wide(label),
+               utf8_to_wide(item_name),
+               258 + m_fields.size(),
+               2
+       );
 
-               auto style = getStyleForElement("item_image_button", spec_btn.fname, "image_button");
+       GUIButtonItemImage *e_btn = GUIButtonItemImage::addButton(Environment,
+                       rect, m_tsrc, data->current_parent, spec_btn.fid, spec_btn.flabel.c_str(),
+                       item_name, m_client);
 
-               spec_btn.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, "");
+       auto style = getStyleForElement("item_image_button", spec_btn.fname, "image_button");
 
-               e_btn->setStyles(style);
+       spec_btn.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, "");
 
-               if (spec_btn.fname == m_focused_element) {
-                       Environment->setFocus(e_btn);
-               }
+       e_btn->setStyles(style);
 
-               spec_btn.ftype = f_Button;
-               rect += data->basepos-padding;
-               spec_btn.rect = rect;
-               m_fields.push_back(spec_btn);
-               return;
+       if (spec_btn.fname == m_focused_element) {
+               Environment->setFocus(e_btn);
        }
-       errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'"  << std::endl;
+
+       spec_btn.ftype = f_Button;
+       rect += data->basepos-padding;
+       spec_btn.rect = rect;
+       m_fields.push_back(spec_btn);
 }
 
 void GUIFormSpecMenu::parseBox(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
+       std::vector<std::string> parts;
+       if (!precheckElement("box", element, 3, 3, parts))
+               return;
 
-       if ((parts.size() == 3) ||
-               ((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               std::vector<std::string> v_pos = split(parts[0], ',');
-               std::vector<std::string> v_geom = split(parts[1], ',');
+       std::vector<std::string> v_pos = split(parts[0], ',');
+       std::vector<std::string> v_geom = split(parts[1], ',');
 
-               MY_CHECKPOS("box", 0);
-               MY_CHECKGEOM("box", 1);
+       MY_CHECKPOS("box", 0);
+       MY_CHECKGEOM("box", 1);
 
-               v2s32 pos;
-               v2s32 geom;
+       v2s32 pos;
+       v2s32 geom;
 
-               if (data->real_coordinates) {
-                       pos = getRealCoordinateBasePos(v_pos);
-                       geom = getRealCoordinateGeometry(v_geom);
-               } else {
-                       pos = getElementBasePos(&v_pos);
-                       geom.X = stof(v_geom[0]) * spacing.X;
-                       geom.Y = stof(v_geom[1]) * spacing.Y;
-               }
+       if (data->real_coordinates) {
+               pos = getRealCoordinateBasePos(v_pos);
+               geom = getRealCoordinateGeometry(v_geom);
+       } else {
+               pos = getElementBasePos(&v_pos);
+               geom.X = stof(v_geom[0]) * spacing.X;
+               geom.Y = stof(v_geom[1]) * spacing.Y;
+       }
 
-               FieldSpec spec(
-                       "",
-                       L"",
-                       L"",
-                       258 + m_fields.size(),
-                       -2
-               );
-               spec.ftype = f_Box;
+       FieldSpec spec(
+               "",
+               L"",
+               L"",
+               258 + m_fields.size(),
+               -2
+       );
+       spec.ftype = f_Box;
 
-               auto style = getDefaultStyleForElement("box", spec.fname);
+       auto style = getDefaultStyleForElement("box", spec.fname);
 
-               video::SColor tmp_color;
-               std::array<video::SColor, 4> colors;
-               std::array<video::SColor, 4> bordercolors = {0x0, 0x0, 0x0, 0x0};
-               std::array<s32, 4> borderwidths = {0, 0, 0, 0};
+       video::SColor tmp_color;
+       std::array<video::SColor, 4> colors;
+       std::array<video::SColor, 4> bordercolors = {0x0, 0x0, 0x0, 0x0};
+       std::array<s32, 4> borderwidths = {0, 0, 0, 0};
 
-               if (parseColorString(parts[2], tmp_color, true, 0x8C)) {
-                       colors = {tmp_color, tmp_color, tmp_color, tmp_color};
-               } else {
-                       colors = style.getColorArray(StyleSpec::COLORS, {0x0, 0x0, 0x0, 0x0});
-                       bordercolors = style.getColorArray(StyleSpec::BORDERCOLORS,
-                               {0x0, 0x0, 0x0, 0x0});
-                       borderwidths = style.getIntArray(StyleSpec::BORDERWIDTHS, {0, 0, 0, 0});
-               }
+       if (parseColorString(parts[2], tmp_color, true, 0x8C)) {
+               colors = {tmp_color, tmp_color, tmp_color, tmp_color};
+       } else {
+               colors = style.getColorArray(StyleSpec::COLORS, {0x0, 0x0, 0x0, 0x0});
+               bordercolors = style.getColorArray(StyleSpec::BORDERCOLORS,
+                       {0x0, 0x0, 0x0, 0x0});
+               borderwidths = style.getIntArray(StyleSpec::BORDERWIDTHS, {0, 0, 0, 0});
+       }
 
-               core::rect<s32> rect(pos, pos + geom);
+       core::rect<s32> rect(pos, pos + geom);
 
-               GUIBox *e = new GUIBox(Environment, data->current_parent, spec.fid, rect,
-                       colors, bordercolors, borderwidths);
-               e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3));
-               e->drop();
+       GUIBox *e = new GUIBox(Environment, data->current_parent, spec.fid, rect,
+               colors, bordercolors, borderwidths);
+       e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3));
+       e->drop();
 
-               m_fields.push_back(spec);
-               return;
-       }
-       errorstream << "Invalid Box element(" << parts.size() << "): '" << element
-               << "'" << std::endl;
+       m_fields.push_back(spec);
 }
 
 void GUIFormSpecMenu::parseBackgroundColor(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       if (!precheckElement("bgcolor", element, 1, 3, parts))
+               return;
+
        const u32 parameter_count = parts.size();
 
-       if ((parameter_count > 2 && m_formspec_version < 3) ||
-                       (parameter_count > 3 && m_formspec_version <= FORMSPEC_API_VERSION)) {
+       if (parameter_count > 2 && m_formspec_version < 3) {
                errorstream << "Invalid bgcolor element(" << parameter_count << "): '"
                                << element << "'" << std::endl;
                return;
@@ -2347,49 +2282,51 @@ void GUIFormSpecMenu::parseBackgroundColor(parserData* data, const std::string &
 
 void GUIFormSpecMenu::parseListColors(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
+       std::vector<std::string> parts;
+       // Legacy Note: If clients older than 5.5.0-dev are supplied with additional arguments,
+       // the tooltip colors will be ignored.
+       if (!precheckElement("listcolors", element, 2, 5, parts))
+               return;
 
-       if (((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) ||
-               ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
-       {
-               parseColorString(parts[0], data->inventorylist_options.slotbg_n, false);
-               parseColorString(parts[1], data->inventorylist_options.slotbg_h, false);
+       if (parts.size() == 4) {
+               // Invalid argument combination
+               errorstream << "Invalid listcolors element(" << parts.size() << "): '"
+                               << element << "'" << std::endl;
+               return;
+       }
 
-               if (parts.size() >= 3) {
-                       if (parseColorString(parts[2], data->inventorylist_options.slotbordercolor,
-                                       false)) {
-                               data->inventorylist_options.slotborder = true;
-                       }
-               }
-               if (parts.size() == 5) {
-                       video::SColor tmp_color;
+       parseColorString(parts[0], data->inventorylist_options.slotbg_n, false);
+       parseColorString(parts[1], data->inventorylist_options.slotbg_h, false);
 
-                       if (parseColorString(parts[3], tmp_color, false))
-                               m_default_tooltip_bgcolor = tmp_color;
-                       if (parseColorString(parts[4], tmp_color, false))
-                               m_default_tooltip_color = tmp_color;
+       if (parts.size() >= 3) {
+               if (parseColorString(parts[2], data->inventorylist_options.slotbordercolor,
+                               false)) {
+                       data->inventorylist_options.slotborder = true;
                }
+       }
+       if (parts.size() >= 5) {
+               video::SColor tmp_color;
 
-               // update all already parsed inventorylists
-               for (GUIInventoryList *e : m_inventorylists) {
-                       e->setSlotBGColors(data->inventorylist_options.slotbg_n,
-                                       data->inventorylist_options.slotbg_h);
-                       e->setSlotBorders(data->inventorylist_options.slotborder,
-                                       data->inventorylist_options.slotbordercolor);
-               }
-               return;
+               if (parseColorString(parts[3], tmp_color, false))
+                       m_default_tooltip_bgcolor = tmp_color;
+               if (parseColorString(parts[4], tmp_color, false))
+                       m_default_tooltip_color = tmp_color;
+       }
+
+       // update all already parsed inventorylists
+       for (GUIInventoryList *e : m_inventorylists) {
+               e->setSlotBGColors(data->inventorylist_options.slotbg_n,
+                               data->inventorylist_options.slotbg_h);
+               e->setSlotBorders(data->inventorylist_options.slotborder,
+                               data->inventorylist_options.slotbordercolor);
        }
-       errorstream<< "Invalid listcolors element(" << parts.size() << "): '" << element << "'"  << std::endl;
 }
 
 void GUIFormSpecMenu::parseTooltip(parserData* data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element,';');
-       if (parts.size() < 2) {
-               errorstream << "Invalid tooltip element(" << parts.size() << "): '"
-                               << element << "'"  << std::endl;
+       std::vector<std::string> parts;
+       if (!precheckElement("tooltip", element, 2, 5, parts))
                return;
-       }
 
        // Get mode and check size
        bool rect_mode = parts[0].find(',') != std::string::npos;
@@ -2529,11 +2466,16 @@ bool GUIFormSpecMenu::parsePositionDirect(parserData *data, const std::string &e
 
 void GUIFormSpecMenu::parsePosition(parserData *data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ',');
+       std::vector<std::string> parts = split(element, ';');
 
-       if (parts.size() == 2) {
-               data->offset.X = stof(parts[0]);
-               data->offset.Y = stof(parts[1]);
+       if (parts.size() == 1 ||
+                       (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
+               std::vector<std::string> v_geom = split(parts[0], ',');
+
+               MY_CHECKGEOM("position", 0);
+
+               data->offset.X = stof(v_geom[0]);
+               data->offset.Y = stof(v_geom[1]);
                return;
        }
 
@@ -2563,11 +2505,16 @@ bool GUIFormSpecMenu::parseAnchorDirect(parserData *data, const std::string &ele
 
 void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ',');
+       std::vector<std::string> parts = split(element, ';');
 
-       if (parts.size() == 2) {
-               data->anchor.X = stof(parts[0]);
-               data->anchor.Y = stof(parts[1]);
+       if (parts.size() == 1 ||
+                       (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
+               std::vector<std::string> v_geom = split(parts[0], ',');
+
+               MY_CHECKGEOM("anchor", 0);
+
+               data->anchor.X = stof(v_geom[0]);
+               data->anchor.Y = stof(v_geom[1]);
                return;
        }
 
@@ -2575,6 +2522,46 @@ void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element)
                        << "'" << std::endl;
 }
 
+bool GUIFormSpecMenu::parsePaddingDirect(parserData *data, const std::string &element)
+{
+       if (element.empty())
+               return false;
+
+       std::vector<std::string> parts = split(element, '[');
+
+       if (parts.size() != 2)
+               return false;
+
+       std::string type = trim(parts[0]);
+       std::string description = trim(parts[1]);
+
+       if (type != "padding")
+               return false;
+
+       parsePadding(data, description);
+
+       return true;
+}
+
+void GUIFormSpecMenu::parsePadding(parserData *data, const std::string &element)
+{
+       std::vector<std::string> parts = split(element, ';');
+
+       if (parts.size() == 1 ||
+                       (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
+               std::vector<std::string> v_geom = split(parts[0], ',');
+
+               MY_CHECKGEOM("padding", 0);
+
+               data->padding.X = stof(v_geom[0]);
+               data->padding.Y = stof(v_geom[1]);
+               return;
+       }
+
+       errorstream << "Invalid padding element (" << parts.size() << "): '" << element
+                       << "'" << std::endl;
+}
+
 bool GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element, bool style_type)
 {
        std::vector<std::string> parts = split(element, ';');
@@ -2713,35 +2700,25 @@ bool GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element, b
 
 void GUIFormSpecMenu::parseSetFocus(const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
-
-       if (parts.size() <= 2 ||
-               (parts.size() > 2 && m_formspec_version > FORMSPEC_API_VERSION))
-       {
-               if (m_is_form_regenerated)
-                       return; // Never focus on resizing
-
-               bool force_focus = parts.size() >= 2 && is_yes(parts[1]);
-               if (force_focus || m_text_dst->m_formname != m_last_formname)
-                       setFocus(parts[0]);
-
+       std::vector<std::string> parts;
+       if (!precheckElement("set_focus", element, 1, 2, parts))
                return;
-       }
 
-       errorstream << "Invalid set_focus element (" << parts.size() << "): '" << element
-               << "'" << std::endl;
+       if (m_is_form_regenerated)
+               return; // Never focus on resizing
+
+       bool force_focus = parts.size() >= 2 && is_yes(parts[1]);
+       if (force_focus || m_text_dst->m_formname != m_last_formname)
+               setFocus(parts[0]);
 }
 
 void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
 {
-       std::vector<std::string> parts = split(element, ';');
+       MY_CHECKCLIENT("model");
 
-       if (parts.size() < 5 || (parts.size() > 10 &&
-                       m_formspec_version <= FORMSPEC_API_VERSION)) {
-               errorstream << "Invalid model element (" << parts.size() << "): '" << element
-                       << "'" << std::endl;
+       std::vector<std::string> parts;
+       if (!precheckElement("model", element, 5, 10, parts))
                return;
-       }
 
        // Avoid length checks by resizing
        if (parts.size() < 10)
@@ -3078,8 +3055,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                checkbox_it.second->drop();
        for (auto &scrollbar_it : m_scrollbars)
                scrollbar_it.second->drop();
-       for (auto &background_it : m_backgrounds)
-               background_it->drop();
        for (auto &tooltip_rect_it : m_tooltip_rects)
                tooltip_rect_it.first->drop();
        for (auto &clickthrough_it : m_clickthrough_elements)
@@ -3091,6 +3066,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
        mydata.screensize = screensize;
        mydata.offset = v2f32(0.5f, 0.5f);
        mydata.anchor = v2f32(0.5f, 0.5f);
+       mydata.padding = v2f32(0.05f, 0.05f);
        mydata.simple_field_count = 0;
 
        // Base position of contents of form
@@ -3100,7 +3076,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
        mydata.current_parent = this;
 
        m_inventorylists.clear();
-       m_backgrounds.clear();
        m_tables.clear();
        m_checkboxes.clear();
        m_scrollbars.clear();
@@ -3193,7 +3168,14 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                }
        }
 
-       /* "no_prepend" element is always after "position" (or  "size" element) if it used */
+       /* "padding" element is always after "anchor" and previous if it is used */
+       for (; i < elements.size(); i++) {
+               if (!parsePaddingDirect(&mydata, elements[i])) {
+                       break;
+               }
+       }
+
+       /* "no_prepend" element is always after "padding" and previous if it used */
        bool enable_prepends = true;
        for (; i < elements.size(); i++) {
                if (elements[i].empty())
@@ -3258,11 +3240,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                        double fitx_imgsize;
                        double fity_imgsize;
 
-                       // Pad the screensize with 5% of the screensize on all sides to ensure
-                       // that even the largest formspecs don't touch the screen borders.
                        v2f padded_screensize(
-                               mydata.screensize.X * 0.9f,
-                               mydata.screensize.Y * 0.9f
+                               mydata.screensize.X * (1.0f - mydata.padding.X * 2.0f),
+                               mydata.screensize.Y * (1.0f - mydata.padding.Y * 2.0f)
                        );
 
                        if (mydata.real_coordinates) {
@@ -3278,13 +3258,15 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                                                ((15.0 / 13.0) * (0.85 + mydata.invsize.Y));
                        }
 
-#ifdef __ANDROID__
+                       s32 min_screen_dim = std::min(padded_screensize.X, padded_screensize.Y);
+
+#ifdef HAVE_TOUCHSCREENGUI
                        // In Android, the preferred imgsize should be larger to accommodate the
                        // smaller screensize.
-                       double prefer_imgsize = padded_screensize.Y / 10 * gui_scaling;
+                       double prefer_imgsize = min_screen_dim / 10 * gui_scaling;
 #else
                        // Desktop computers have more space, so try to fit 15 coordinates.
-                       double prefer_imgsize = padded_screensize.Y / 15 * gui_scaling;
+                       double prefer_imgsize = min_screen_dim / 15 * gui_scaling;
 #endif
                        // Try to use the preferred imgsize, but if that's bigger than the maximum
                        // size, use the maximum size.
@@ -3347,6 +3329,15 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
        gui::IGUIFont *old_font = skin->getFont();
        skin->setFont(m_font);
 
+       // Add a new element that will hold all the background elements as its children.
+       // Because it is the first added element, all backgrounds will be behind all
+       // the other elements.
+       // (We use an arbitrarily big rect. The actual size is determined later by
+       // clipping to `this`.)
+       core::rect<s32> background_parent_rect(0, 0, 100000, 100000);
+       mydata.background_parent.reset(new gui::IGUIElement(EGUIET_ELEMENT, Environment,
+                       this, -1, background_parent_rect));
+
        pos_offset = v2f32();
 
        // used for formspec versions < 3
@@ -3602,15 +3593,6 @@ void GUIFormSpecMenu::drawMenu()
                }
        }
 
-       /*
-               Draw backgrounds
-       */
-       for (gui::IGUIElement *e : m_backgrounds) {
-               e->setVisible(true);
-               e->draw();
-               e->setVisible(false);
-       }
-
        // Some elements are only visible while being drawn
        for (gui::IGUIElement *e : m_clickthrough_elements)
                e->setVisible(true);
@@ -3741,7 +3723,7 @@ void GUIFormSpecMenu::showTooltip(const std::wstring &text,
        v2u32 screenSize = Environment->getVideoDriver()->getScreenSize();
        int tooltip_offset_x = m_btn_height;
        int tooltip_offset_y = m_btn_height;
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        tooltip_offset_x *= 3;
        tooltip_offset_y  = 0;
        if (m_pointer.X > (s32)screenSize.X / 2)
index 926de66d54dc1ed97ae24b6024cf6e5995a1f972..3fedb3b78cd550438a6a8bf9cc5b355c90d6ee95 100644 (file)
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <unordered_set>
 
 #include "irrlichttypes_extrabloated.h"
+#include "irr_ptr.h"
 #include "inventorymanager.h"
 #include "modalMenu.h"
 #include "guiInventoryList.h"
@@ -229,7 +230,7 @@ class GUIFormSpecMenu : public GUIModalMenu
                return m_selected_item;
        }
 
-       const u16 getSelectedAmount() const
+       u16 getSelectedAmount() const
        {
                return m_selected_amount;
        }
@@ -279,6 +280,8 @@ class GUIFormSpecMenu : public GUIModalMenu
        v2s32 getElementBasePos(const std::vector<std::string> *v_pos);
        v2s32 getRealCoordinateBasePos(const std::vector<std::string> &v_pos);
        v2s32 getRealCoordinateGeometry(const std::vector<std::string> &v_geom);
+       bool precheckElement(const std::string &name, const std::string &element,
+               size_t args_min, size_t args_max, std::vector<std::string> &parts);
 
        std::unordered_map<std::string, std::vector<StyleSpec>> theme_by_type;
        std::unordered_map<std::string, std::vector<StyleSpec>> theme_by_name;
@@ -311,7 +314,6 @@ class GUIFormSpecMenu : public GUIModalMenu
 
        std::vector<GUIInventoryList *> m_inventorylists;
        std::vector<ListRingSpec> m_inventory_rings;
-       std::vector<gui::IGUIElement *> m_backgrounds;
        std::unordered_map<std::string, bool> field_close_on_enter;
        std::unordered_map<std::string, bool> m_dropdown_index_event;
        std::vector<FieldSpec> m_fields;
@@ -366,12 +368,14 @@ class GUIFormSpecMenu : public GUIModalMenu
                v2s32 size;
                v2f32 offset;
                v2f32 anchor;
+               v2f32 padding;
                core::rect<s32> rect;
                v2s32 basepos;
                v2u32 screensize;
                GUITable::TableOptions table_options;
                GUITable::TableColumns table_columns;
                gui::IGUIElement *current_parent = nullptr;
+               irr_ptr<gui::IGUIElement> background_parent;
 
                GUIInventoryList::Options inventorylist_options;
 
@@ -447,6 +451,8 @@ class GUIFormSpecMenu : public GUIModalMenu
        void parsePosition(parserData *data, const std::string &element);
        bool parseAnchorDirect(parserData *data, const std::string &element);
        void parseAnchor(parserData *data, const std::string &element);
+       bool parsePaddingDirect(parserData *data, const std::string &element);
+       void parsePadding(parserData *data, const std::string &element);
        bool parseStyle(parserData *data, const std::string &element, bool style_type);
        void parseSetFocus(const std::string &element);
        void parseModel(parserData *data, const std::string &element);
index ccfdcb81d4d30bc3c77670f89983f328b63b7d26..40450ce5f6387806d041bf55222827d40be93ab2 100644 (file)
@@ -17,31 +17,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "IGUIEnvironment.h"
-#include "IGUIElement.h"
+#include "guiHyperText.h"
 #include "guiScrollBar.h"
-#include "IGUIFont.h"
-#include <vector>
-#include <list>
-#include <unordered_map>
-using namespace irr::gui;
 #include "client/fontengine.h"
-#include <SColor.h>
 #include "client/tile.h"
 #include "IVideoDriver.h"
 #include "client/client.h"
 #include "client/renderingengine.h"
 #include "hud.h"
-#include "guiHyperText.h"
 #include "util/string.h"
+#include "irrlicht_changes/CGUITTFont.h"
 
-bool check_color(const std::string &str)
+using namespace irr::gui;
+
+static bool check_color(const std::string &str)
 {
        irr::video::SColor color;
        return parseColorString(str, color, false);
 }
 
-bool check_integer(const std::string &str)
+static bool check_integer(const std::string &str)
 {
        if (str.empty())
                return false;
@@ -616,12 +611,10 @@ TextDrawer::TextDrawer(const wchar_t *text, Client *client,
                                if (e.font) {
                                        e.dim.Width = e.font->getDimension(e.text.c_str()).Width;
                                        e.dim.Height = e.font->getDimension(L"Yy").Height;
-#if USE_FREETYPE
                                        if (e.font->getType() == irr::gui::EGFT_CUSTOM) {
-                                               e.baseline = e.dim.Height - 1 -
-                                                       ((irr::gui::CGUITTFont *)e.font)->getAscender() / 64;
+                                               CGUITTFont *tmp = static_cast<CGUITTFont*>(e.font);
+                                               e.baseline = e.dim.Height - 1 - tmp->getAscender() / 64;
                                        }
-#endif
                                } else {
                                        e.dim = {0, 0};
                                }
index 5b936262e88ab4aa256836fff75a31c4ef05518d..04c664df545127ef99b2e0035ef31916b07a7ad8 100644 (file)
@@ -19,16 +19,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #pragma once
 
-#include "config.h" // for USE_FREETYPE
+#include <vector>
+#include <list>
+#include <unordered_map>
+#include <string>
+#include "irrlichttypes_extrabloated.h"
 
 using namespace irr;
 
 class ISimpleTextureSource;
 class Client;
-
-#if USE_FREETYPE
-#include "irrlicht_changes/CGUITTFont.h"
-#endif
+class GUIScrollBar;
 
 class ParsedText
 {
index 74cd62f5b37f5f6b34a24994502277944a726108..c983260f6a90807f6ddecbeeb599c7ffcb3fd5b4 100644 (file)
@@ -25,6 +25,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <IGUIStaticText.h>
 #include <IGUIFont.h>
 
+#ifdef HAVE_TOUCHSCREENGUI
+       #include "client/renderingengine.h"
+#endif
+
 #include "porting.h"
 #include "gettext.h"
 
@@ -79,8 +83,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
        /*
                Calculate new sizes and positions
        */
-#ifdef __ANDROID__
-       const float s = m_gui_scale * porting::getDisplayDensity() / 2;
+#ifdef HAVE_TOUCHSCREENGUI
+       const float s = m_gui_scale * RenderingEngine::getDisplayDensity() / 2;
 #else
        const float s = m_gui_scale;
 #endif
index e09209bd90af02ef366de2aeeef2ade8a982d592..ca692f6cbc7d5c7216f0979236f8b15f5b5fa979 100644 (file)
@@ -1024,48 +1024,6 @@ void GUISkin::draw2DRectangle(IGUIElement* element,
 }\r
 \r
 \r
-//! Writes attributes of the object.\r
-//! Implement this to expose the attributes of your scene node animator for\r
-//! scripting languages, editors, debuggers or xml serialization purposes.\r
-void GUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const\r
-{\r
-       u32 i;\r
-       for (i=0; i<EGDC_COUNT; ++i)\r
-               out->addColor(GUISkinColorNames[i], Colors[i]);\r
-\r
-       for (i=0; i<EGDS_COUNT; ++i)\r
-               out->addInt(GUISkinSizeNames[i], Sizes[i]);\r
-\r
-       for (i=0; i<EGDT_COUNT; ++i)\r
-               out->addString(GUISkinTextNames[i], Texts[i].c_str());\r
-\r
-       for (i=0; i<EGDI_COUNT; ++i)\r
-               out->addInt(GUISkinIconNames[i], Icons[i]);\r
-}\r
-\r
-\r
-//! Reads attributes of the object.\r
-//! Implement this to set the attributes of your scene node animator for\r
-//! scripting languages, editors, debuggers or xml deserialization purposes.\r
-void GUISkin::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)\r
-{\r
-       // TODO: This is not nice code for downward compatibility, whenever new values are added and users\r
-       // load an old skin the corresponding values will be set to 0.\r
-       u32 i;\r
-       for (i=0; i<EGDC_COUNT; ++i)\r
-               Colors[i] = in->getAttributeAsColor(GUISkinColorNames[i]);\r
-\r
-       for (i=0; i<EGDS_COUNT; ++i)\r
-               Sizes[i] = in->getAttributeAsInt(GUISkinSizeNames[i]);\r
-\r
-       for (i=0; i<EGDT_COUNT; ++i)\r
-               Texts[i] = in->getAttributeAsStringW(GUISkinTextNames[i]);\r
-\r
-       for (i=0; i<EGDI_COUNT; ++i)\r
-               Icons[i] = in->getAttributeAsInt(GUISkinIconNames[i]);\r
-}\r
-\r
-\r
 //! gets the colors\r
 // PATCH\r
 void GUISkin::getColors(video::SColor* colors)\r
index bbb900f9f5d80b6ede702916c8cd30377d24150c..fa9b27bddaec2e8c2e4156e8d2867184cb53fe57 100644 (file)
@@ -290,16 +290,6 @@ namespace gui
                //! get the type of this skin\r
                virtual EGUI_SKIN_TYPE getType() const;\r
 \r
-               //! Writes attributes of the object.\r
-               //! Implement this to expose the attributes of your scene node animator for\r
-               //! scripting languages, editors, debuggers or xml serialization purposes.\r
-               virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const;\r
-\r
-               //! Reads attributes of the object.\r
-               //! Implement this to set the attributes of your scene node animator for\r
-               //! scripting languages, editors, debuggers or xml deserialization purposes.\r
-               virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);\r
-\r
                //! gets the colors\r
                virtual void getColors(video::SColor* colors); // ::PATCH:\r
 \r
index cab2e19fd9af040c6e5a27c2ae34948a5072dba5..79ae1aea31525f9af2b3a08a35e0db4da0e947cf 100644 (file)
@@ -77,9 +77,10 @@ GUITable::GUITable(gui::IGUIEnvironment *env,
        setTabStop(true);
        setTabOrder(-1);
        updateAbsolutePosition();
+#ifdef HAVE_TOUCHSCREENGUI
+       float density = 1; // dp scaling is applied by the skin
+#else
        float density = RenderingEngine::getDisplayDensity();
-#ifdef __ANDROID__
-       density = 1; // dp scaling is applied by the skin
 #endif
        core::rect<s32> relative_rect = m_scrollbar->getRelativePosition();
        s32 width = (relative_rect.getWidth() / (2.0 / 3.0)) * density *
index 1016de38979b895dff3990756a9bc9016ab8ea03..56a5d2cb9ed39796b76ca2a58adb4b7bc9fceca1 100644 (file)
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #ifdef HAVE_TOUCHSCREENGUI
 #include "touchscreengui.h"
+#include "client/renderingengine.h"
 #endif
 
 // clang-format off
@@ -40,8 +41,8 @@ GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent,
                m_remap_dbl_click(remap_dbl_click)
 {
        m_gui_scale = g_settings->getFloat("gui_scaling");
-#ifdef __ANDROID__
-       float d = porting::getDisplayDensity();
+#ifdef HAVE_TOUCHSCREENGUI
+       float d = RenderingEngine::getDisplayDensity();
        m_gui_scale *= 1.1 - 0.3 * d + 0.2 * d * d;
 #endif
        setVisible(true);
@@ -183,7 +184,7 @@ static bool isChild(gui::IGUIElement *tocheck, gui::IGUIElement *parent)
        return false;
 }
 
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
 
 bool GUIModalMenu::simulateMouseEvent(
                gui::IGUIElement *target, ETOUCH_INPUT_EVENT touch_event)
@@ -217,6 +218,8 @@ bool GUIModalMenu::simulateMouseEvent(
 
 void GUIModalMenu::enter(gui::IGUIElement *hovered)
 {
+       if (!hovered)
+               return;
        sanity_check(!m_hovered);
        m_hovered.grab(hovered);
        SEvent gui_event{};
@@ -286,7 +289,9 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
                        return retval;
                }
        }
+#endif
 
+#ifdef HAVE_TOUCHSCREENGUI
        if (event.EventType == EET_TOUCH_INPUT_EVENT) {
                irr_ptr<GUIModalMenu> holder;
                holder.grab(this); // keep this alive until return (it might be dropped downstream [?])
index ed0da320527f2f68d761635cba249721255b8329..06e78f06b465ca2fdd100857b769e269c622d24f 100644 (file)
@@ -75,10 +75,10 @@ class GUIModalMenu : public gui::IGUIElement
        v2u32 m_screensize_old;
        float m_gui_scale;
 #ifdef __ANDROID__
-       v2s32 m_down_pos;
        std::string m_jni_field_name;
 #endif
 #ifdef HAVE_TOUCHSCREENGUI
+       v2s32 m_down_pos;
        bool m_touchscreen_visible = true;
 #endif
 
@@ -102,7 +102,7 @@ class GUIModalMenu : public gui::IGUIElement
        // wants to launch other menus
        bool m_allow_focus_removal = false;
 
-#ifdef __ANDROID__
+#ifdef HAVE_TOUCHSCREENGUI
        irr_ptr<gui::IGUIElement> m_hovered;
 
        bool simulateMouseEvent(gui::IGUIElement *target, ETOUCH_INPUT_EVENT touch_event);
index b29285e2f8dc2872465b2e211720dabdc732c7b7..f71ef3799a5966cef0f2b98b411234d5e38de052 100644 (file)
@@ -94,20 +94,29 @@ void ProfilerGraph::draw(s32 x_left, s32 y_bottom, video::IVideoDriver *driver,
                                show_min = 0;
                }
 
-               s32 texth = 15;
+               const s32 texth = 15;
                char buf[10];
-               porting::mt_snprintf(buf, sizeof(buf), "%.3g", show_max);
+               if (floorf(show_max) == show_max)
+                       porting::mt_snprintf(buf, sizeof(buf), "%.5g", show_max);
+               else
+                       porting::mt_snprintf(buf, sizeof(buf), "%.3g", show_max);
                font->draw(utf8_to_wide(buf).c_str(),
                                core::rect<s32>(textx, y - graphh, textx2,
                                                y - graphh + texth),
                                meta.color);
-               porting::mt_snprintf(buf, sizeof(buf), "%.3g", show_min);
+
+               if (floorf(show_min) == show_min)
+                       porting::mt_snprintf(buf, sizeof(buf), "%.5g", show_min);
+               else
+                       porting::mt_snprintf(buf, sizeof(buf), "%.3g", show_min);
                font->draw(utf8_to_wide(buf).c_str(),
                                core::rect<s32>(textx, y - texth, textx2, y), meta.color);
+
                font->draw(utf8_to_wide(id).c_str(),
                                core::rect<s32>(textx, y - graphh / 2 - texth / 2, textx2,
                                                y - graphh / 2 + texth / 2),
                                meta.color);
+
                s32 graph1y = y;
                s32 graph1h = graphh;
                bool relativegraph = (show_min != 0 && show_min != show_max);
index eb20b7e70e9e20ca18182e20ff4a02c1838837a9..ebe1a632520ab6b6edf5cf4f9cb3762f0eb36230 100644 (file)
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/numeric.h"
 #include "porting.h"
 #include "client/guiscalingfilter.h"
+#include "client/renderingengine.h"
 
 #include <iostream>
 #include <algorithm>
@@ -426,7 +427,7 @@ TouchScreenGUI::TouchScreenGUI(IrrlichtDevice *device, IEventReceiver *receiver)
        m_joystick_triggers_aux1 = g_settings->getBool("virtual_joystick_triggers_aux1");
        m_screensize = m_device->getVideoDriver()->getScreenSize();
        button_size = MYMIN(m_screensize.Y / 4.5f,
-                       porting::getDisplayDensity() *
+                       RenderingEngine::getDisplayDensity() *
                        g_settings->getFloat("hud_scaling") * 65.0f);
 }
 
@@ -668,9 +669,9 @@ void TouchScreenGUI::handleReleaseEvent(size_t evt_id)
        if (button != after_last_element_id) {
                // handle button events
                handleButtonEvent(button, evt_id, false);
-       } else if (evt_id == m_move_id) {
+       } else if (m_has_move_id && evt_id == m_move_id) {
                // handle the point used for moving view
-               m_move_id = -1;
+               m_has_move_id = false;
 
                // if this pointer issued a mouse event issue symmetric release here
                if (m_move_sent_as_mouse_event) {
@@ -692,8 +693,8 @@ void TouchScreenGUI::handleReleaseEvent(size_t evt_id)
        }
 
        // handle joystick
-       else if (evt_id == m_joystick_id) {
-               m_joystick_id = -1;
+       else if (m_has_joystick_id && evt_id == m_joystick_id) {
+               m_has_joystick_id = false;
 
                // reset joystick
                for (unsigned int i = 0; i < 4; i++)
@@ -776,7 +777,8 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                        if ((m_fixed_joystick && dxj * dxj + dyj * dyj <= button_size * button_size * 1.5 * 1.5) ||
                                        (!m_fixed_joystick && event.TouchInput.X < m_screensize.X / 3.0f)) {
                                // If we don't already have a starting point for joystick make this the one.
-                               if (m_joystick_id == -1) {
+                               if (!m_has_joystick_id) {
+                                       m_has_joystick_id           = true;
                                        m_joystick_id               = event.TouchInput.ID;
                                        m_joystick_has_really_moved = false;
 
@@ -796,7 +798,8 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                                }
                        } else {
                                // If we don't already have a moving point make this the moving one.
-                               if (m_move_id == -1) {
+                               if (!m_has_move_id) {
+                                       m_has_move_id              = true;
                                        m_move_id                  = event.TouchInput.ID;
                                        m_move_has_really_moved    = false;
                                        m_move_downtime            = porting::getTimeMs();
@@ -819,7 +822,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                                v2s32(event.TouchInput.X, event.TouchInput.Y))
                        return;
 
-               if (m_move_id != -1) {
+               if (m_has_move_id) {
                        if ((event.TouchInput.ID == m_move_id) &&
                                (!m_move_sent_as_mouse_event)) {
 
@@ -862,7 +865,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                        }
                }
 
-               if (m_joystick_id != -1 && event.TouchInput.ID == m_joystick_id) {
+               if (m_has_joystick_id && event.TouchInput.ID == m_joystick_id) {
                        s32 X = event.TouchInput.X;
                        s32 Y = event.TouchInput.Y;
 
@@ -941,7 +944,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                        }
                }
 
-               if (m_move_id == -1 && m_joystick_id == -1)
+               if (!m_has_move_id && !m_has_joystick_id)
                        handleChangedButton(event);
        }
 }
@@ -1086,7 +1089,7 @@ void TouchScreenGUI::step(float dtime)
                        button.repeatcounter += dtime;
 
                        // in case we're moving around digging does not happen
-                       if (m_move_id != -1)
+                       if (m_has_move_id)
                                m_move_has_really_moved = true;
 
                        if (button.repeatcounter < button.repeatdelay)
@@ -1114,7 +1117,7 @@ void TouchScreenGUI::step(float dtime)
        }
 
        // if a new placed pointer isn't moved for some time start digging
-       if ((m_move_id != -1) &&
+       if (m_has_move_id &&
                        (!m_move_has_really_moved) &&
                        (!m_move_sent_as_mouse_event)) {
 
index ad5abae87c78d6d33feea8a6272ca3220fa579d9..6b36c0d599eaab0ed34eb357acc90bdcbe600a77 100644 (file)
@@ -228,13 +228,15 @@ class TouchScreenGUI
         */
        line3d<f32> m_shootline;
 
-       int m_move_id = -1;
+       bool m_has_move_id = false;
+       size_t m_move_id;
        bool m_move_has_really_moved = false;
        u64 m_move_downtime = 0;
        bool m_move_sent_as_mouse_event = false;
        v2s32 m_move_downlocation = v2s32(-10000, -10000);
 
-       int m_joystick_id = -1;
+       bool m_has_joystick_id = false;
+       size_t m_joystick_id;
        bool m_joystick_has_really_moved = false;
        bool m_fixed_joystick = false;
        bool m_joystick_triggers_aux1 = false;
index 1307bfec3af0072bfd94bddcb64a3a406fdfdef5..16f0791c994c601f3be8b0f547cd7f63f12ccf88 100644 (file)
@@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "noise.h"
 
 static std::mutex g_httpfetch_mutex;
-static std::unordered_map<unsigned long, std::queue<HTTPFetchResult>>
+static std::unordered_map<u64, std::queue<HTTPFetchResult>>
        g_httpfetch_results;
 static PcgRandom g_callerid_randomness;
 
@@ -52,22 +52,21 @@ HTTPFetchRequest::HTTPFetchRequest() :
 
 static void httpfetch_deliver_result(const HTTPFetchResult &fetch_result)
 {
-       unsigned long caller = fetch_result.caller;
+       u64 caller = fetch_result.caller;
        if (caller != HTTPFETCH_DISCARD) {
                MutexAutoLock lock(g_httpfetch_mutex);
                g_httpfetch_results[caller].emplace(fetch_result);
        }
 }
 
-static void httpfetch_request_clear(unsigned long caller);
+static void httpfetch_request_clear(u64 caller);
 
-unsigned long httpfetch_caller_alloc()
+u64 httpfetch_caller_alloc()
 {
        MutexAutoLock lock(g_httpfetch_mutex);
 
-       // Check each caller ID except HTTPFETCH_DISCARD
-       const unsigned long discard = HTTPFETCH_DISCARD;
-       for (unsigned long caller = discard + 1; caller != discard; ++caller) {
+       // Check each caller ID except reserved ones
+       for (u64 caller = HTTPFETCH_CID_START; caller != 0; ++caller) {
                auto it = g_httpfetch_results.find(caller);
                if (it == g_httpfetch_results.end()) {
                        verbosestream << "httpfetch_caller_alloc: allocating "
@@ -79,18 +78,17 @@ unsigned long httpfetch_caller_alloc()
        }
 
        FATAL_ERROR("httpfetch_caller_alloc: ran out of caller IDs");
-       return discard;
 }
 
-unsigned long httpfetch_caller_alloc_secure()
+u64 httpfetch_caller_alloc_secure()
 {
        MutexAutoLock lock(g_httpfetch_mutex);
 
        // Generate random caller IDs and make sure they're not
-       // already used or equal to HTTPFETCH_DISCARD
+       // already used or reserved.
        // Give up after 100 tries to prevent infinite loop
-       u8 tries = 100;
-       unsigned long caller;
+       size_t tries = 100;
+       u64 caller;
 
        do {
                caller = (((u64) g_callerid_randomness.next()) << 32) |
@@ -100,7 +98,8 @@ unsigned long httpfetch_caller_alloc_secure()
                        FATAL_ERROR("httpfetch_caller_alloc_secure: ran out of caller IDs");
                        return HTTPFETCH_DISCARD;
                }
-       } while (g_httpfetch_results.find(caller) != g_httpfetch_results.end());
+       } while (caller >= HTTPFETCH_CID_START &&
+               g_httpfetch_results.find(caller) != g_httpfetch_results.end());
 
        verbosestream << "httpfetch_caller_alloc_secure: allocating "
                << caller << std::endl;
@@ -110,7 +109,7 @@ unsigned long httpfetch_caller_alloc_secure()
        return caller;
 }
 
-void httpfetch_caller_free(unsigned long caller)
+void httpfetch_caller_free(u64 caller)
 {
        verbosestream<<"httpfetch_caller_free: freeing "
                        <<caller<<std::endl;
@@ -122,7 +121,7 @@ void httpfetch_caller_free(unsigned long caller)
        }
 }
 
-bool httpfetch_async_get(unsigned long caller, HTTPFetchResult &fetch_result)
+bool httpfetch_async_get(u64 caller, HTTPFetchResult &fetch_result)
 {
        MutexAutoLock lock(g_httpfetch_mutex);
 
@@ -242,7 +241,6 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
 
        // Set static cURL options
        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
-       curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3);
        curl_easy_setopt(curl, CURLOPT_ENCODING, "gzip");
@@ -393,10 +391,17 @@ const HTTPFetchResult * HTTPFetchOngoing::complete(CURLcode res)
        }
 
        if (res != CURLE_OK) {
-               errorstream << request.url << " not found ("
-                       << curl_easy_strerror(res) << ")"
-                       << " (response code " << result.response_code << ")"
+               errorstream << "HTTPFetch for " << request.url << " failed ("
+                       << curl_easy_strerror(res) << ")" << std::endl;
+       } else if (result.response_code >= 400) {
+               errorstream << "HTTPFetch for " << request.url
+                       << " returned response code " << result.response_code
                        << std::endl;
+               if (result.caller == HTTPFETCH_PRINT_ERR && !result.data.empty()) {
+                       errorstream << "Response body:" << std::endl;
+                       safe_print_string(errorstream, result.data);
+                       errorstream << std::endl;
+               }
        }
 
        return &result;
@@ -474,7 +479,7 @@ class CurlFetchThread : public Thread
                m_requests.push_back(req);
        }
 
-       void requestClear(unsigned long caller, Event *event)
+       void requestClear(u64 caller, Event *event)
        {
                Request req;
                req.type = RT_CLEAR;
@@ -505,7 +510,7 @@ class CurlFetchThread : public Thread
 
                }
                else if (req.type == RT_CLEAR) {
-                       unsigned long caller = req.fetch_request.caller;
+                       u64 caller = req.fetch_request.caller;
 
                        // Abort all ongoing fetches for the caller
                        for (std::vector<HTTPFetchOngoing*>::iterator
@@ -778,7 +783,7 @@ void httpfetch_async(const HTTPFetchRequest &fetch_request)
                g_httpfetch_thread->start();
 }
 
-static void httpfetch_request_clear(unsigned long caller)
+static void httpfetch_request_clear(u64 caller)
 {
        if (g_httpfetch_thread->isRunning()) {
                Event event;
@@ -827,7 +832,7 @@ void httpfetch_async(const HTTPFetchRequest &fetch_request)
        httpfetch_deliver_result(fetch_result);
 }
 
-static void httpfetch_request_clear(unsigned long caller)
+static void httpfetch_request_clear(u64 caller)
 {
 }
 
index 3b9f17f0a53cd68a6639fdfe03fa914e1b2a41c9..a4901e63b71d119bc1cee24751429ff62a584cd5 100644 (file)
@@ -23,10 +23,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/string.h"
 #include "config.h"
 
-// Can be used in place of "caller" in asynchronous transfers to discard result
-// (used as default value of "caller")
+// These can be used in place of "caller" in to specify special handling.
+// Discard result (used as default value of "caller").
 #define HTTPFETCH_DISCARD 0
+// Indicates that the result should not be discarded when performing a
+// synchronous request (since a real caller ID is not needed for synchronous
+// requests because the result does not have to be retrieved later).
 #define HTTPFETCH_SYNC 1
+// Print response body to console if the server returns an error code.
+#define HTTPFETCH_PRINT_ERR 2
+// Start of regular allocated caller IDs.
+#define HTTPFETCH_CID_START 3
 
 //  Methods
 enum HttpMethod : u8
@@ -43,11 +50,11 @@ struct HTTPFetchRequest
 
        // Identifies the caller (for asynchronous requests)
        // Ignored by httpfetch_sync
-       unsigned long caller = HTTPFETCH_DISCARD;
+       u64 caller = HTTPFETCH_DISCARD;
 
        // Some number that identifies the request
        // (when the same caller issues multiple httpfetch_async calls)
-       unsigned long request_id = 0;
+       u64 request_id = 0;
 
        // Timeout for the whole transfer, in milliseconds
        long timeout;
@@ -85,8 +92,8 @@ struct HTTPFetchResult
        long response_code = 0;
        std::string data = "";
        // The caller and request_id from the corresponding HTTPFetchRequest.
-       unsigned long caller = HTTPFETCH_DISCARD;
-       unsigned long request_id = 0;
+       u64 caller = HTTPFETCH_DISCARD;
+       u64 request_id = 0;
 
        HTTPFetchResult() = default;
 
@@ -107,19 +114,19 @@ void httpfetch_async(const HTTPFetchRequest &fetch_request);
 
 // If any fetch for the given caller ID is complete, removes it from the
 // result queue, sets the fetch result and returns true. Otherwise returns false.
-bool httpfetch_async_get(unsigned long caller, HTTPFetchResult &fetch_result);
+bool httpfetch_async_get(u64 caller, HTTPFetchResult &fetch_result);
 
 // Allocates a caller ID for httpfetch_async
 // Not required if you want to set caller = HTTPFETCH_DISCARD
-unsigned long httpfetch_caller_alloc();
+u64 httpfetch_caller_alloc();
 
 // Allocates a non-predictable caller ID for httpfetch_async
-unsigned long httpfetch_caller_alloc_secure();
+u64 httpfetch_caller_alloc_secure();
 
 // Frees a caller ID allocated with httpfetch_caller_alloc
 // Note: This can be expensive, because the httpfetch thread is told
 // to stop any ongoing fetches for the given caller.
-void httpfetch_caller_free(unsigned long caller);
+void httpfetch_caller_free(u64 caller);
 
 // Performs a synchronous HTTP request. This blocks and therefore should
 // only be used from background threads.
index e4ad7940fa28cdf48b4411bf2c01e679e38790c7..841c907587eb456f199791d94c0ba6185d256549 100644 (file)
@@ -63,5 +63,6 @@ const struct EnumString es_HudBuiltinElement[] =
        {HUD_FLAG_BREATHBAR_VISIBLE,     "breathbar"},
        {HUD_FLAG_MINIMAP_VISIBLE,       "minimap"},
        {HUD_FLAG_MINIMAP_RADAR_VISIBLE, "minimap_radar"},
+       {HUD_FLAG_BASIC_DEBUG,           "basic_debug"},
        {0, NULL},
 };
index 769966688d91d002e564c6c32c832964615e4101..173633fcc824283bd34f0ad1de45da5881dc9249 100644 (file)
--- a/src/hud.h
+++ b/src/hud.h
@@ -47,6 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define HUD_FLAG_BREATHBAR_VISIBLE     (1 << 4)
 #define HUD_FLAG_MINIMAP_VISIBLE       (1 << 5)
 #define HUD_FLAG_MINIMAP_RADAR_VISIBLE (1 << 6)
+#define HUD_FLAG_BASIC_DEBUG           (1 << 7)
 
 #define HUD_PARAM_HOTBAR_ITEMCOUNT 1
 #define HUD_PARAM_HOTBAR_IMAGE 2
index da6517e6298ef3a561dcbf407d957125a796610c..6d2b7fba3530b49846954fb8353c5cab807604dc 100644 (file)
@@ -503,11 +503,6 @@ void InventoryList::deSerialize(std::istream &is)
        throw SerializationError(ss.str());
 }
 
-InventoryList::InventoryList(const InventoryList &other)
-{
-       *this = other;
-}
-
 InventoryList & InventoryList::operator = (const InventoryList &other)
 {
        m_items = other.m_items;
@@ -535,21 +530,6 @@ bool InventoryList::operator == (const InventoryList &other) const
        return true;
 }
 
-const std::string &InventoryList::getName() const
-{
-       return m_name;
-}
-
-u32 InventoryList::getSize() const
-{
-       return m_items.size();
-}
-
-u32 InventoryList::getWidth() const
-{
-       return m_width;
-}
-
 u32 InventoryList::getUsedSlots() const
 {
        u32 num = 0;
@@ -560,23 +540,6 @@ u32 InventoryList::getUsedSlots() const
        return num;
 }
 
-u32 InventoryList::getFreeSlots() const
-{
-       return getSize() - getUsedSlots();
-}
-
-const ItemStack& InventoryList::getItem(u32 i) const
-{
-       assert(i < m_size); // Pre-condition
-       return m_items[i];
-}
-
-ItemStack& InventoryList::getItem(u32 i)
-{
-       assert(i < m_size); // Pre-condition
-       return m_items[i];
-}
-
 ItemStack InventoryList::changeItem(u32 i, const ItemStack &newitem)
 {
        if(i >= m_items.size())
@@ -965,16 +928,6 @@ InventoryList * Inventory::getList(const std::string &name)
        return m_lists[i];
 }
 
-std::vector<const InventoryList*> Inventory::getLists()
-{
-       std::vector<const InventoryList*> lists;
-       lists.reserve(m_lists.size());
-       for (auto list : m_lists) {
-               lists.push_back(list);
-       }
-       return lists;
-}
-
 bool Inventory::deleteList(const std::string &name)
 {
        s32 i = getListIndex(name);
@@ -995,7 +948,7 @@ const InventoryList *Inventory::getList(const std::string &name) const
        return m_lists[i];
 }
 
-const s32 Inventory::getListIndex(const std::string &name) const
+s32 Inventory::getListIndex(const std::string &name) const
 {
        for(u32 i=0; i<m_lists.size(); i++)
        {
index 6c84f5fd12ac7f734cfed949397ae7efbf56561d..8b31de3a8ae39ee563764fd09991e89ef11fad51 100644 (file)
@@ -198,7 +198,7 @@ class InventoryList
        void serialize(std::ostream &os, bool incremental) const;
        void deSerialize(std::istream &is);
 
-       InventoryList(const InventoryList &other);
+       InventoryList(const InventoryList &other) { *this = other; }
        InventoryList & operator = (const InventoryList &other);
        bool operator == (const InventoryList &other) const;
        bool operator != (const InventoryList &other) const
@@ -206,16 +206,25 @@ class InventoryList
                return !(*this == other);
        }
 
-       const std::string &getName() const;
-       u32 getSize() const;
-       u32 getWidth() const;
+       const std::string &getName() const { return m_name; }
+       u32 getSize() const { return static_cast<u32>(m_items.size()); }
+       u32 getWidth() const { return m_width; }
        // Count used slots
        u32 getUsedSlots() const;
-       u32 getFreeSlots() const;
 
        // Get reference to item
-       const ItemStack& getItem(u32 i) const;
-       ItemStack& getItem(u32 i);
+       const ItemStack &getItem(u32 i) const
+       {
+               assert(i < m_size); // Pre-condition
+               return m_items[i];
+       }
+       ItemStack &getItem(u32 i)
+       {
+               assert(i < m_size); // Pre-condition
+               return m_items[i];
+       }
+       // Get reference to all items
+       const std::vector<ItemStack> &getItems() const { return m_items; }
        // Returns old item. Parameter can be an empty item.
        ItemStack changeItem(u32 i, const ItemStack &newitem);
        // Delete item
@@ -272,7 +281,7 @@ class InventoryList
 private:
        std::vector<ItemStack> m_items;
        std::string m_name;
-       u32 m_size;
+       u32 m_size; // always the same as m_items.size()
        u32 m_width = 0;
        IItemDefManager *m_itemdef;
        bool m_dirty = true;
@@ -302,7 +311,7 @@ class Inventory
        InventoryList * addList(const std::string &name, u32 size);
        InventoryList * getList(const std::string &name);
        const InventoryList * getList(const std::string &name) const;
-       std::vector<const InventoryList*> getLists();
+       const std::vector<InventoryList *> &getLists() const { return m_lists; }
        bool deleteList(const std::string &name);
        // A shorthand for adding items. Returns leftover item (possibly empty).
        ItemStack addItem(const std::string &listname, const ItemStack &newitem)
@@ -336,7 +345,7 @@ class Inventory
        }
 private:
        // -1 if not found
-       const s32 getListIndex(const std::string &name) const;
+       s32 getListIndex(const std::string &name) const;
 
        std::vector<InventoryList*> m_lists;
        IItemDefManager *m_itemdef;
index a159bf786f58910c116f173bb2ce6cbb41ad3a49..ecdb56a972240b09e5245d007c7613b0ded38437 100644 (file)
@@ -172,7 +172,7 @@ void IMoveAction::onPutAndOnTake(const ItemStack &src_item, ServerActiveObject *
                sa->player_inventory_OnPut(*this, src_item, player);
        else
                assert(false);
-       
+
        if (from_inv.type == InventoryLocation::DETACHED)
                sa->detached_inventory_OnTake(*this, src_item, player);
        else if (from_inv.type == InventoryLocation::NODEMETA)
index e785ea8373fcd7243b3eca814368ffe1a3ebd539..787f4cd5afc78050f54043abc5aeaa825c8e2823 100644 (file)
@@ -478,7 +478,7 @@ CGUITTGlyphPage* CGUITTFont::getLastGlyphPage() const
 CGUITTGlyphPage* CGUITTFont::createGlyphPage(const u8& pixel_mode)
 {
        CGUITTGlyphPage* page = 0;
-       
+
        // Name of our page.
        io::path name("TTFontGlyphPage_");
        name += tt_face->family_name;
index 87c88f7e808a6472641756fab40c4e38cf48dfd3..19f431af351cf12f317eef6fd209dca8ba4eeeaa 100644 (file)
@@ -1,14 +1,9 @@
 if (BUILD_CLIENT)
        set(client_irrlicht_changes_SRCS
                ${CMAKE_CURRENT_SOURCE_DIR}/static_text.cpp
+               ${CMAKE_CURRENT_SOURCE_DIR}/CGUITTFont.cpp
        )
 
-       if (USE_FREETYPE)
-               set(client_irrlicht_changes_SRCS ${client_irrlicht_changes_SRCS}
-                       ${CMAKE_CURRENT_SOURCE_DIR}/CGUITTFont.cpp
-               )
-       endif()
-
        # CMake require us to set a local scope and then parent scope
        # Else the last set win in parent scope
        set(client_irrlicht_changes_SRCS ${client_irrlicht_changes_SRCS} PARENT_SCOPE)
index 8908a91f78aea080b2c6106b178e2833d3b59cd6..baf0ea626c311cb1eda7d520879c5fabb309e8c2 100644 (file)
 #include <rect.h>
 #include <SColor.h>
 
-#if USE_FREETYPE
-       #include "CGUITTFont.h"
-#endif
-
+#include "CGUITTFont.h"
 #include "util/string.h"
 
 namespace irr
 {
 
-#if USE_FREETYPE
-
 namespace gui
 {
 //! constructor
@@ -108,14 +103,12 @@ void StaticText::draw()
                                        font->getDimension(str.c_str()).Width;
                        }
 
-#if USE_FREETYPE
                        if (font->getType() == irr::gui::EGFT_CUSTOM) {
-                               irr::gui::CGUITTFont *tmp = static_cast<irr::gui::CGUITTFont*>(font);
+                               CGUITTFont *tmp = static_cast<CGUITTFont*>(font);
                                tmp->draw(str,
                                        r, HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER,
                                        (RestrainTextInside ? &AbsoluteClippingRect : NULL));
                        } else
-#endif
                        {
                                // Draw non-colored text
                                font->draw(str.c_str(),
@@ -588,54 +581,8 @@ s32 StaticText::getTextWidth() const
 }
 
 
-//! Writes attributes of the element.
-//! Implement this to expose the attributes of your element for
-//! scripting languages, editors, debuggers or xml serialization purposes.
-void StaticText::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
-{
-       IGUIStaticText::serializeAttributes(out,options);
-
-       out->addBool    ("Border",              Border);
-       out->addBool    ("OverrideColorEnabled",true);
-       out->addBool    ("OverrideBGColorEnabled",ColoredText.hasBackground());
-       out->addBool    ("WordWrap",            WordWrap);
-       out->addBool    ("Background",          Background);
-       out->addBool    ("RightToLeft",         RightToLeft);
-       out->addBool    ("RestrainTextInside",  RestrainTextInside);
-       out->addColor   ("OverrideColor",       ColoredText.getDefaultColor());
-       out->addColor   ("BGColor",             ColoredText.getBackground());
-       out->addEnum    ("HTextAlign",          HAlign, GUIAlignmentNames);
-       out->addEnum    ("VTextAlign",          VAlign, GUIAlignmentNames);
-
-       // out->addFont ("OverrideFont",        OverrideFont);
-}
-
-
-//! Reads attributes of the element
-void StaticText::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
-{
-       IGUIStaticText::deserializeAttributes(in,options);
-
-       Border = in->getAttributeAsBool("Border");
-       setWordWrap(in->getAttributeAsBool("WordWrap"));
-       Background = in->getAttributeAsBool("Background");
-       RightToLeft = in->getAttributeAsBool("RightToLeft");
-       RestrainTextInside = in->getAttributeAsBool("RestrainTextInside");
-       if (in->getAttributeAsBool("OverrideColorEnabled"))
-               ColoredText.setDefaultColor(in->getAttributeAsColor("OverrideColor"));
-       if (in->getAttributeAsBool("OverrideBGColorEnabled"))
-               ColoredText.setBackground(in->getAttributeAsColor("BGColor"));
-
-       setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames),
-                      (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames));
-
-       // OverrideFont = in->getAttributeAsFont("OverrideFont");
-}
-
 } // end namespace gui
 
-#endif // USE_FREETYPE
-
 } // end namespace irr
 
 
index 83bbf4c3d709a300b3293f2d8f6db91aebd2fc62..74ef620084f2f6a46e07ba13ff8c1d0b5cb841d5 100644 (file)
@@ -20,7 +20,6 @@
 #include "config.h"
 #include <IGUIEnvironment.h>
 
-#if USE_FREETYPE
 
 namespace irr
 {
@@ -184,12 +183,6 @@ namespace gui
                //! Checks if the text should be interpreted as right-to-left text
                virtual bool isRightToLeft() const;
 
-               //! Writes attributes of the element.
-               virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
-
-               //! Reads attributes of the element
-               virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
-
                virtual bool hasType(EGUI_ELEMENT_TYPE t) const {
                        return (t == EGUIET_ENRICHED_STATIC_TEXT) || (t == EGUIET_STATIC_TEXT);
                };
@@ -236,41 +229,6 @@ inline void setStaticText(irr::gui::IGUIStaticText *static_text, const EnrichedS
        }
 }
 
-#else // USE_FREETYPE
-
-namespace irr
-{
-namespace gui
-{
-
-class StaticText
-{
-public:
-       static irr::gui::IGUIStaticText *add(
-               irr::gui::IGUIEnvironment *guienv,
-               const EnrichedString &text,
-               const core::rect< s32 > &rectangle,
-               bool border = false,
-               bool wordWrap = true,
-               irr::gui::IGUIElement *parent = NULL,
-               s32 id = -1,
-               bool fillBackground = false)
-       {
-               return guienv->addStaticText(text.c_str(), rectangle, border, wordWrap, parent, id, fillBackground);
-       }
-};
-
-} // end namespace gui
-
-} // end namespace irr
-
-inline void setStaticText(irr::gui::IGUIStaticText *static_text, const EnrichedString &text)
-{
-       static_text->setText(text.c_str());
-}
-
-#endif
-
 inline void setStaticText(irr::gui::IGUIStaticText *static_text, const wchar_t *text)
 {
        setStaticText(static_text, EnrichedString(text, static_text->getOverrideColor()));
diff --git a/src/lighting.h b/src/lighting.h
new file mode 100644 (file)
index 0000000..e0d9cee
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+Minetest
+Copyright (C) 2021 x2048, Dmitry Kostenko <codeforsmile@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+/** Describes ambient light settings for a player
+ */
+struct Lighting
+{
+    float shadow_intensity {0.0f};
+};
index 3c61414e901c57e1626104d3c0e0df55b79be347..51652fe0a059eeaa918b6a313e272c489fdd2498 100644 (file)
@@ -35,43 +35,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <cerrno>
 #include <cstring>
 
-const int BUFFER_LENGTH = 256;
-
-class StringBuffer : public std::streambuf {
+class LevelTarget : public LogTarget {
 public:
-       StringBuffer() {
-               buffer_index = 0;
-       }
-
-       int overflow(int c);
-       virtual void flush(const std::string &buf) = 0;
-       std::streamsize xsputn(const char *s, std::streamsize n);
-       void push_back(char c);
-
-private:
-       char buffer[BUFFER_LENGTH];
-       int buffer_index;
-};
-
-
-class LogBuffer : public StringBuffer {
-public:
-       LogBuffer(Logger &logger, LogLevel lev) :
-               logger(logger),
-               level(lev)
+       LevelTarget(Logger &logger, LogLevel level, bool raw = false) :
+               m_logger(logger),
+               m_level(level),
+               m_raw(raw)
        {}
 
-       void flush(const std::string &buffer);
-
-private:
-       Logger &logger;
-       LogLevel level;
-};
+       virtual bool hasOutput() override {
+               return m_logger.hasOutput(m_level);
+       }
 
+       virtual void log(const std::string &buf) override {
+               if (!m_raw) {
+                       m_logger.log(m_level, buf);
+               } else {
+                       m_logger.logRaw(m_level, buf);
+               }
+       }
 
-class RawLogBuffer : public StringBuffer {
-public:
-       void flush(const std::string &buffer);
+private:
+       Logger &m_logger;
+       LogLevel m_level;
+       bool m_raw;
 };
 
 ////
@@ -80,31 +67,33 @@ class RawLogBuffer : public StringBuffer {
 
 Logger g_logger;
 
+#ifdef __ANDROID__
+AndroidLogOutput stdout_output;
+AndroidLogOutput stderr_output;
+#else
 StreamLogOutput stdout_output(std::cout);
 StreamLogOutput stderr_output(std::cerr);
-std::ostream null_stream(NULL);
-
-RawLogBuffer raw_buf;
-
-LogBuffer none_buf(g_logger, LL_NONE);
-LogBuffer error_buf(g_logger, LL_ERROR);
-LogBuffer warning_buf(g_logger, LL_WARNING);
-LogBuffer action_buf(g_logger, LL_ACTION);
-LogBuffer info_buf(g_logger, LL_INFO);
-LogBuffer verbose_buf(g_logger, LL_VERBOSE);
-
-// Connection
-std::ostream *dout_con_ptr = &null_stream;
-std::ostream *derr_con_ptr = &verbosestream;
-
-// Common streams
-std::ostream rawstream(&raw_buf);
-std::ostream dstream(&none_buf);
-std::ostream errorstream(&error_buf);
-std::ostream warningstream(&warning_buf);
-std::ostream actionstream(&action_buf);
-std::ostream infostream(&info_buf);
-std::ostream verbosestream(&verbose_buf);
+#endif
+
+LevelTarget none_target_raw(g_logger, LL_NONE, true);
+LevelTarget none_target(g_logger, LL_NONE);
+LevelTarget error_target(g_logger, LL_ERROR);
+LevelTarget warning_target(g_logger, LL_WARNING);
+LevelTarget action_target(g_logger, LL_ACTION);
+LevelTarget info_target(g_logger, LL_INFO);
+LevelTarget verbose_target(g_logger, LL_VERBOSE);
+LevelTarget trace_target(g_logger, LL_TRACE);
+
+thread_local LogStream dstream(none_target);
+thread_local LogStream rawstream(none_target_raw);
+thread_local LogStream errorstream(error_target);
+thread_local LogStream warningstream(warning_target);
+thread_local LogStream actionstream(action_target);
+thread_local LogStream infostream(info_target);
+thread_local LogStream verbosestream(verbose_target);
+thread_local LogStream tracestream(trace_target);
+thread_local LogStream derr_con(verbose_target);
+thread_local LogStream dout_con(trace_target);
 
 // Android
 #ifdef __ANDROID__
@@ -118,29 +107,15 @@ static unsigned int g_level_to_android[] = {
        //ANDROID_LOG_INFO,
        ANDROID_LOG_DEBUG,    // LL_INFO
        ANDROID_LOG_VERBOSE,  // LL_VERBOSE
+       ANDROID_LOG_VERBOSE,  // LL_TRACE
 };
 
-class AndroidSystemLogOutput : public ICombinedLogOutput {
-       public:
-               AndroidSystemLogOutput()
-               {
-                       g_logger.addOutput(this);
-               }
-               ~AndroidSystemLogOutput()
-               {
-                       g_logger.removeOutput(this);
-               }
-               void logRaw(LogLevel lev, const std::string &line)
-               {
-                       STATIC_ASSERT(ARRLEN(g_level_to_android) == LL_MAX,
-                               mismatch_between_android_and_internal_loglevels);
-                       __android_log_print(g_level_to_android[lev],
-                               PROJECT_NAME_C, "%s", line.c_str());
-               }
-};
-
-AndroidSystemLogOutput g_android_log_output;
-
+void AndroidLogOutput::logRaw(LogLevel lev, const std::string &line) {
+       STATIC_ASSERT(ARRLEN(g_level_to_android) == LL_MAX,
+               mismatch_between_android_and_internal_loglevels);
+       __android_log_print(g_level_to_android[lev],
+               PROJECT_NAME_C, "%s", line.c_str());
+}
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -164,6 +139,8 @@ LogLevel Logger::stringToLevel(const std::string &name)
                return LL_INFO;
        else if (name == "verbose")
                return LL_VERBOSE;
+       else if (name == "trace")
+               return LL_TRACE;
        else
                return LL_MAX;
 }
@@ -176,21 +153,26 @@ void Logger::addOutput(ILogOutput *out)
 void Logger::addOutput(ILogOutput *out, LogLevel lev)
 {
        m_outputs[lev].push_back(out);
+       m_has_outputs[lev] = true;
 }
 
 void Logger::addOutputMasked(ILogOutput *out, LogLevelMask mask)
 {
        for (size_t i = 0; i < LL_MAX; i++) {
-               if (mask & LOGLEVEL_TO_MASKLEVEL(i))
+               if (mask & LOGLEVEL_TO_MASKLEVEL(i)) {
                        m_outputs[i].push_back(out);
+                       m_has_outputs[i] = true;
+               }
        }
 }
 
 void Logger::addOutputMaxLevel(ILogOutput *out, LogLevel lev)
 {
        assert(lev < LL_MAX);
-       for (size_t i = 0; i <= lev; i++)
+       for (size_t i = 0; i <= lev; i++) {
                m_outputs[i].push_back(out);
+               m_has_outputs[i] = true;
+       }
 }
 
 LogLevelMask Logger::removeOutput(ILogOutput *out)
@@ -203,6 +185,7 @@ LogLevelMask Logger::removeOutput(ILogOutput *out)
                if (it != m_outputs[i].end()) {
                        ret_mask |= LOGLEVEL_TO_MASKLEVEL(i);
                        m_outputs[i].erase(it);
+                       m_has_outputs[i] = !m_outputs[i].empty();
                }
        }
        return ret_mask;
@@ -236,6 +219,7 @@ const std::string Logger::getLevelLabel(LogLevel lev)
                "ACTION",
                "INFO",
                "VERBOSE",
+               "TRACE",
        };
        assert(lev < LL_MAX && lev >= 0);
        STATIC_ASSERT(ARRLEN(names) == LL_MAX,
@@ -297,7 +281,6 @@ void Logger::logToOutputs(LogLevel lev, const std::string &combined,
                m_outputs[lev][i]->log(lev, combined, time, thread_name, payload_text);
 }
 
-
 ////
 //// *LogOutput methods
 ////
@@ -349,6 +332,7 @@ void StreamLogOutput::logRaw(LogLevel lev, const std::string &line)
                        m_stream << "\033[37m";
                        break;
                case LL_VERBOSE:
+               case LL_TRACE:
                        // verbose is darker than info
                        m_stream << "\033[2m";
                        break;
@@ -396,6 +380,7 @@ void LogOutputBuffer::logRaw(LogLevel lev, const std::string &line)
                        color = "\x1b(c@#BBB)";
                        break;
                case LL_VERBOSE: // dark grey
+               case LL_TRACE:
                        color = "\x1b(c@#888)";
                        break;
                default: break;
@@ -404,47 +389,3 @@ void LogOutputBuffer::logRaw(LogLevel lev, const std::string &line)
 
        m_buffer.push(color.append(line));
 }
-
-////
-//// *Buffer methods
-////
-
-int StringBuffer::overflow(int c)
-{
-       push_back(c);
-       return c;
-}
-
-
-std::streamsize StringBuffer::xsputn(const char *s, std::streamsize n)
-{
-       for (int i = 0; i < n; ++i)
-               push_back(s[i]);
-       return n;
-}
-
-void StringBuffer::push_back(char c)
-{
-       if (c == '\n' || c == '\r') {
-               if (buffer_index)
-                       flush(std::string(buffer, buffer_index));
-               buffer_index = 0;
-       } else {
-               buffer[buffer_index++] = c;
-               if (buffer_index >= BUFFER_LENGTH) {
-                       flush(std::string(buffer, buffer_index));
-                       buffer_index = 0;
-               }
-       }
-}
-
-
-void LogBuffer::flush(const std::string &buffer)
-{
-       logger.log(level, buffer);
-}
-
-void RawLogBuffer::flush(const std::string &buffer)
-{
-       g_logger.logRaw(LL_NONE, buffer);
-}
index 6ed6b1fb710b272ae66a8e81614850cdad14ba63..5c6ba7d64ff41e559cdddef2e08be9f1975f8db1 100644 (file)
--- a/src/log.h
+++ b/src/log.h
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #pragma once
 
+#include <atomic>
 #include <map>
 #include <queue>
 #include <string>
@@ -28,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #if !defined(_WIN32)  // POSIX
        #include <unistd.h>
 #endif
+#include "util/basic_macros.h"
+#include "util/stream.h"
 #include "irrlichttypes.h"
 
 class ILogOutput;
@@ -39,6 +42,7 @@ enum LogLevel {
        LL_ACTION,  // In-game actions
        LL_INFO,
        LL_VERBOSE,
+       LL_TRACE,
        LL_MAX,
 };
 
@@ -67,12 +71,13 @@ class Logger {
        // Logs without a prefix
        void logRaw(LogLevel lev, const std::string &text);
 
-       void setTraceEnabled(bool enable) { m_trace_enabled = enable; }
-       bool getTraceEnabled() { return m_trace_enabled; }
-
        static LogLevel stringToLevel(const std::string &name);
        static const std::string getLevelLabel(LogLevel lev);
 
+       bool hasOutput(LogLevel level) {
+               return m_has_outputs[level].load(std::memory_order_relaxed);
+       }
+
        static LogColor color_mode;
 
 private:
@@ -84,6 +89,7 @@ class Logger {
        const std::string getThreadName();
 
        std::vector<ILogOutput *> m_outputs[LL_MAX];
+       std::atomic<bool> m_has_outputs[LL_MAX];
 
        // Should implement atomic loads and stores (even though it's only
        // written to when one thread has access currently).
@@ -91,7 +97,6 @@ class Logger {
        volatile bool m_silenced_levels[LL_MAX];
        std::map<std::thread::id, std::string> m_thread_names;
        mutable std::mutex m_mutex;
-       bool m_trace_enabled;
 };
 
 class ILogOutput {
@@ -185,35 +190,178 @@ class LogOutputBuffer : public ICombinedLogOutput {
        Logger &m_logger;
 };
 
+#ifdef __ANDROID__
+class AndroidLogOutput : public ICombinedLogOutput {
+public:
+       void logRaw(LogLevel lev, const std::string &line);
+};
+#endif
 
-extern StreamLogOutput stdout_output;
-extern StreamLogOutput stderr_output;
-extern std::ostream null_stream;
+/*
+ * LogTarget
+ *
+ * This is the interface that sits between the LogStreams and the global logger.
+ * Primarily used to route streams to log levels, but could also enable other
+ * custom behavior.
+ *
+ */
+class LogTarget {
+public:
+       // Must be thread-safe. These can be called from any thread.
+       virtual bool hasOutput() = 0;
+       virtual void log(const std::string &buf) = 0;
+};
 
-extern std::ostream *dout_con_ptr;
-extern std::ostream *derr_con_ptr;
-extern std::ostream *derr_server_ptr;
 
-extern Logger g_logger;
+/*
+ * StreamProxy
+ *
+ * An ostream-like object that can proxy to a real ostream or do nothing,
+ * depending on how it is configured. See LogStream below.
+ *
+ */
+class StreamProxy {
+public:
+       StreamProxy(std::ostream *os) : m_os(os) { }
+
+       template<typename T>
+       StreamProxy& operator<<(T&& arg) {
+               if (m_os) {
+                       *m_os << std::forward<T>(arg);
+               }
+               return *this;
+       }
 
-// Writes directly to all LL_NONE log outputs for g_logger with no prefix.
-extern std::ostream rawstream;
+       StreamProxy& operator<<(std::ostream& (*manip)(std::ostream&)) {
+               if (m_os) {
+                       *m_os << manip;
+               }
+               return *this;
+       }
 
-extern std::ostream errorstream;
-extern std::ostream warningstream;
-extern std::ostream actionstream;
-extern std::ostream infostream;
-extern std::ostream verbosestream;
-extern std::ostream dstream;
+private:
+       std::ostream *m_os;
+};
 
-#define TRACEDO(x) do {               \
-       if (g_logger.getTraceEnabled()) { \
-               x;                            \
-       }                                 \
-} while (0)
 
-#define TRACESTREAM(x) TRACEDO(verbosestream x)
+/*
+ * LogStream
+ *
+ * The public interface for log streams (infostream, verbosestream, etc).
+ *
+ * LogStream minimizes the work done when a given stream is off. (meaning
+ * it has no output targets, so it goes to /dev/null)
+ *
+ * For example, consider:
+ *
+ *     verbosestream << "hello world" << 123 << std::endl;
+ *
+ * The compiler evaluates this as:
+ *
+ *   (((verbosestream << "hello world") << 123) << std::endl)
+ *      ^                            ^
+ *
+ * If `verbosestream` is on, the innermost expression (marked by ^) will return
+ * a StreamProxy that forwards to a real ostream, that feeds into the logger.
+ * However, if `verbosestream` is off, it will return a StreamProxy that does
+ * nothing on all later operations. Specifically, CPU time won't be wasted
+ * writing "hello world" and 123 into a buffer, or formatting the log entry.
+ *
+ * It is also possible to directly check if the stream is on/off:
+ *
+ *   if (verbosestream) {
+ *       auto data = ComputeExpensiveDataForTheLog();
+ *       verbosestream << data << endl;
+ *   }
+ *
+*/
 
-#define dout_con (*dout_con_ptr)
-#define derr_con (*derr_con_ptr)
+class LogStream {
+public:
+       LogStream() = delete;
+       DISABLE_CLASS_COPY(LogStream);
+
+       LogStream(LogTarget &target) :
+               m_target(target),
+               m_buffer(std::bind(&LogStream::internalFlush, this, std::placeholders::_1)),
+               m_dummy_buffer(),
+               m_stream(&m_buffer),
+               m_dummy_stream(&m_dummy_buffer),
+               m_proxy(&m_stream),
+               m_dummy_proxy(nullptr) { }
+
+       template<typename T>
+       StreamProxy& operator<<(T&& arg) {
+               StreamProxy& sp = m_target.hasOutput() ? m_proxy : m_dummy_proxy;
+               sp << std::forward<T>(arg);
+               return sp;
+       }
 
+       StreamProxy& operator<<(std::ostream& (*manip)(std::ostream&)) {
+               StreamProxy& sp = m_target.hasOutput() ? m_proxy : m_dummy_proxy;
+               sp << manip;
+               return sp;
+       }
+
+       operator bool() {
+               return m_target.hasOutput();
+       }
+
+       void internalFlush(const std::string &buf) {
+               m_target.log(buf);
+       }
+
+       operator std::ostream&() {
+               return m_target.hasOutput() ? m_stream : m_dummy_stream;
+       }
+
+private:
+       // 10 streams per thread x (256 + overhead) ~ 3K per thread
+       static const int BUFFER_LENGTH = 256;
+       LogTarget &m_target;
+       StringStreamBuffer<BUFFER_LENGTH> m_buffer;
+       DummyStreamBuffer m_dummy_buffer;
+       std::ostream m_stream;
+       std::ostream m_dummy_stream;
+       StreamProxy m_proxy;
+       StreamProxy m_dummy_proxy;
+
+};
+
+#ifdef __ANDROID__
+extern AndroidLogOutput stdout_output;
+extern AndroidLogOutput stderr_output;
+#else
+extern StreamLogOutput stdout_output;
+extern StreamLogOutput stderr_output;
+#endif
+
+extern Logger g_logger;
+
+/*
+ * By making the streams thread_local, each thread has its own
+ * private buffer. Two or more threads can write to the same stream
+ * simultaneously (lock-free), and there won't be any interference.
+ *
+ * The finished lines are sent to a LogTarget which is a global (not thread-local)
+ * object, and from there relayed to g_logger. The final writes are serialized
+ * by the mutex in g_logger.
+*/
+
+extern thread_local LogStream dstream;
+extern thread_local LogStream rawstream;  // Writes directly to all LL_NONE log outputs with no prefix.
+extern thread_local LogStream errorstream;
+extern thread_local LogStream warningstream;
+extern thread_local LogStream actionstream;
+extern thread_local LogStream infostream;
+extern thread_local LogStream verbosestream;
+extern thread_local LogStream tracestream;
+// TODO: Search/replace these with verbose/tracestream
+extern thread_local LogStream derr_con;
+extern thread_local LogStream dout_con;
+
+#define TRACESTREAM(x) do {    \
+       if (tracestream) {      \
+               tracestream x;  \
+       }                       \
+} while (0)
index 1044b327a5a02ceb015daf54f7d0c4ef4ff231cf..ebd1f740ecf1fdf8bbdc242e836224e226982fd8 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes.h" // must be included before anything irrlicht, see comment in the file
 #include "irrlicht.h" // createDevice
 #include "irrlichttypes_extrabloated.h"
+#include "benchmark/benchmark.h"
 #include "chat_interface.h"
 #include "debug.h"
 #include "unittest/test.h"
@@ -65,6 +66,14 @@ extern "C" {
 #error Minetest cannot be built without exceptions or RTTI
 #endif
 
+#if defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__clang__) && \
+       (__GNUC__ < 11 || (__GNUC__ == 11 && __GNUC_MINOR__ < 1))
+// see e.g. https://github.com/minetest/minetest/issues/10137
+#warning ==================================
+#warning 32-bit MinGW gcc before 11.1 has known issues with crashes on thread exit, you should upgrade.
+#warning ==================================
+#endif
+
 #define DEBUGFILE "debug.txt"
 #define DEFAULT_SERVER_PORT 30000
 
@@ -204,7 +213,19 @@ int main(int argc, char *argv[])
                return 1;
 #endif
        }
+
+       // Run benchmarks
+       if (cmd_args.getFlag("run-benchmarks")) {
+#if BUILD_BENCHMARKS
+               return run_benchmarks();
+#else
+               errorstream << "Benchmark support is not enabled in this binary. "
+                       << "If you want to enable it, compile project with BUILD_BENCHMARKS=1 flag."
+                       << std::endl;
+               return 1;
 #endif
+       }
+#endif // __ANDROID__
 
        GameStartData game_params;
 #ifdef SERVER
@@ -269,6 +290,8 @@ static void set_allowed_options(OptionList *allowed_options)
                        _("Set network port (UDP)"))));
        allowed_options->insert(std::make_pair("run-unittests", ValueSpec(VALUETYPE_FLAG,
                        _("Run the unit tests and exit"))));
+       allowed_options->insert(std::make_pair("run-benchmarks", ValueSpec(VALUETYPE_FLAG,
+                       _("Run the benchmarks and exit"))));
        allowed_options->insert(std::make_pair("map-dir", ValueSpec(VALUETYPE_STRING,
                        _("Same as --world (deprecated)"))));
        allowed_options->insert(std::make_pair("world", ValueSpec(VALUETYPE_STRING,
@@ -299,6 +322,8 @@ static void set_allowed_options(OptionList *allowed_options)
                _("Migrate from current players backend to another (Only works when using minetestserver or with --server)"))));
        allowed_options->insert(std::make_pair("migrate-auth", ValueSpec(VALUETYPE_STRING,
                _("Migrate from current auth backend to another (Only works when using minetestserver or with --server)"))));
+       allowed_options->insert(std::make_pair("migrate-mod-storage", ValueSpec(VALUETYPE_STRING,
+               _("Migrate from current mod storage backend to another (Only works when using minetestserver or with --server)"))));
        allowed_options->insert(std::make_pair("terminal", ValueSpec(VALUETYPE_FLAG,
                        _("Feature an interactive terminal (Only works when using minetestserver or with --server)"))));
        allowed_options->insert(std::make_pair("recompress", ValueSpec(VALUETYPE_FLAG,
@@ -443,14 +468,6 @@ static bool setup_log_params(const Settings &cmd_args)
                }
        }
 
-       // If trace is enabled, enable logging of certain things
-       if (cmd_args.getFlag("trace")) {
-               dstream << _("Enabling trace level debug output") << std::endl;
-               g_logger.setTraceEnabled(true);
-               dout_con_ptr = &verbosestream; // This is somewhat old
-               socket_enable_debug_output = true; // Sockets doesn't use log.h
-       }
-
        // In certain cases, output info level on stderr
        if (cmd_args.getFlag("info") || cmd_args.getFlag("verbose") ||
                        cmd_args.getFlag("trace") || cmd_args.getFlag("speedtests"))
@@ -460,6 +477,12 @@ static bool setup_log_params(const Settings &cmd_args)
        if (cmd_args.getFlag("verbose") || cmd_args.getFlag("trace"))
                g_logger.addOutput(&stderr_output, LL_VERBOSE);
 
+       if (cmd_args.getFlag("trace")) {
+               dstream << _("Enabling trace level debug output") << std::endl;
+               g_logger.addOutput(&stderr_output, LL_TRACE);
+               socket_enable_debug_output = true;
+       }
+
        return true;
 }
 
@@ -589,7 +612,7 @@ static void init_log_streams(const Settings &cmd_args)
                warningstream << "Deprecated use of debug_log_level with an "
                        "integer value; please update your configuration." << std::endl;
                static const char *lev_name[] =
-                       {"", "error", "action", "info", "verbose"};
+                       {"", "error", "action", "info", "verbose", "trace"};
                int lev_i = atoi(conf_loglev.c_str());
                if (lev_i < 0 || lev_i >= (int)ARRLEN(lev_name)) {
                        warningstream << "Supplied invalid debug_log_level!"
@@ -886,6 +909,9 @@ static bool run_dedicated_server(const GameParams &game_params, const Settings &
        if (cmd_args.exists("migrate-auth"))
                return ServerEnvironment::migrateAuthDatabase(game_params, cmd_args);
 
+       if (cmd_args.exists("migrate-mod-storage"))
+               return Server::migrateModStorageDatabase(game_params, cmd_args);
+
        if (cmd_args.getFlag("recompress"))
                return recompress_map_database(game_params, cmd_args, bind_addr);
 
index 1648adec3d4b1c5a7ad83efe49d369ae721f59ba..7bc1334b0fbf9aa2238e7abfe29e2006e5c74628 100644 (file)
@@ -154,13 +154,6 @@ void Map::listAllLoadedBlocks(std::vector<v3s16> &dst)
        }
 }
 
-bool Map::isNodeUnderground(v3s16 p)
-{
-       v3s16 blockpos = getNodeBlockPos(p);
-       MapBlock *block = getBlockNoCreateNoEx(blockpos);
-       return block && block->getIsUnderground();
-}
-
 bool Map::isValidPosition(v3s16 p)
 {
        v3s16 blockpos = getNodeBlockPos(p);
@@ -187,24 +180,32 @@ MapNode Map::getNode(v3s16 p, bool *is_valid_position)
        return node;
 }
 
-// throws InvalidPositionException if not found
-void Map::setNode(v3s16 p, MapNode & n)
+static void set_node_in_block(MapBlock *block, v3s16 relpos, MapNode n)
 {
-       v3s16 blockpos = getNodeBlockPos(p);
-       MapBlock *block = getBlockNoCreate(blockpos);
-       v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
        // Never allow placing CONTENT_IGNORE, it causes problems
        if(n.getContent() == CONTENT_IGNORE){
+               const NodeDefManager *nodedef = block->getParent()->getNodeDefManager();
+               v3s16 blockpos = block->getPos();
+               v3s16 p = blockpos * MAP_BLOCKSIZE + relpos;
                bool temp_bool;
-               errorstream<<"Map::setNode(): Not allowing to place CONTENT_IGNORE"
+               errorstream<<"Not allowing to place CONTENT_IGNORE"
                                <<" while trying to replace \""
-                               <<m_nodedef->get(block->getNodeNoCheck(relpos, &temp_bool)).name
+                               <<nodedef->get(block->getNodeNoCheck(relpos, &temp_bool)).name
                                <<"\" at "<<PP(p)<<" (block "<<PP(blockpos)<<")"<<std::endl;
                return;
        }
        block->setNodeNoCheck(relpos, n);
 }
 
+// throws InvalidPositionException if not found
+void Map::setNode(v3s16 p, MapNode & n)
+{
+       v3s16 blockpos = getNodeBlockPos(p);
+       MapBlock *block = getBlockNoCreate(blockpos);
+       v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+       set_node_in_block(block, relpos, n);
+}
+
 void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                std::map<v3s16, MapBlock*> &modified_blocks,
                bool remove_metadata)
@@ -212,8 +213,14 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        // Collect old node for rollback
        RollbackNode rollback_oldnode(this, p, m_gamedef);
 
+       v3s16 blockpos = getNodeBlockPos(p);
+       MapBlock *block = getBlockNoCreate(blockpos);
+       if (block->isDummy())
+               throw InvalidPositionException();
+       v3s16 relpos = p - blockpos * MAP_BLOCKSIZE;
+
        // This is needed for updating the lighting
-       MapNode oldnode = getNode(p);
+       MapNode oldnode = block->getNodeUnsafe(relpos);
 
        // Remove node metadata
        if (remove_metadata) {
@@ -221,18 +228,29 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        }
 
        // Set the node on the map
-       // Ignore light (because calling voxalgo::update_lighting_nodes)
-       n.setLight(LIGHTBANK_DAY, 0, m_nodedef);
-       n.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
-       setNode(p, n);
+       const ContentFeatures &cf = m_nodedef->get(n);
+       const ContentFeatures &oldcf = m_nodedef->get(oldnode);
+       if (cf.lightingEquivalent(oldcf)) {
+               // No light update needed, just copy over the old light.
+               n.setLight(LIGHTBANK_DAY, oldnode.getLightRaw(LIGHTBANK_DAY, oldcf), cf);
+               n.setLight(LIGHTBANK_NIGHT, oldnode.getLightRaw(LIGHTBANK_NIGHT, oldcf), cf);
+               set_node_in_block(block, relpos, n);
+
+               modified_blocks[blockpos] = block;
+       } else {
+               // Ignore light (because calling voxalgo::update_lighting_nodes)
+               n.setLight(LIGHTBANK_DAY, 0, cf);
+               n.setLight(LIGHTBANK_NIGHT, 0, cf);
+               set_node_in_block(block, relpos, n);
 
-       // Update lighting
-       std::vector<std::pair<v3s16, MapNode> > oldnodes;
-       oldnodes.emplace_back(p, oldnode);
-       voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
+               // Update lighting
+               std::vector<std::pair<v3s16, MapNode> > oldnodes;
+               oldnodes.emplace_back(p, oldnode);
+               voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
 
-       for (auto &modified_block : modified_blocks) {
-               modified_block.second->expireDayNightDiff();
+               for (auto &modified_block : modified_blocks) {
+                       modified_block.second->expireDayNightDiff();
+               }
        }
 
        // Report for rollback
@@ -243,22 +261,6 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                action.setSetNode(p, rollback_oldnode, rollback_newnode);
                m_gamedef->rollback()->reportAction(action);
        }
-
-       /*
-               Add neighboring liquid nodes and this node to transform queue.
-               (it's vital for the node itself to get updated last, if it was removed.)
-        */
-
-       for (const v3s16 &dir : g_7dirs) {
-               v3s16 p2 = p + dir;
-
-               bool is_valid_position;
-               MapNode n2 = getNode(p2, &is_valid_position);
-               if(is_valid_position &&
-                               (m_nodedef->get(n2).isLiquid() ||
-                               n2.getContent() == CONTENT_AIR))
-                       m_transforming_liquid.push_back(p2);
-       }
 }
 
 void Map::removeNodeAndUpdate(v3s16 p,
@@ -339,7 +341,7 @@ struct TimeOrderedMapBlock {
 void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
                std::vector<v3s16> *unloaded_blocks)
 {
-       bool save_before_unloading = (mapType() == MAPTYPE_SERVER);
+       bool save_before_unloading = maySaveBlocks();
 
        // Profile modified reasons
        Profiler modprofiler;
@@ -349,6 +351,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
        u32 saved_blocks_count = 0;
        u32 block_count_all = 0;
 
+       const auto start_time = porting::getTimeUs();
        beginSave();
 
        // If there is no practical limit, we spare creation of mapblock_queue
@@ -390,6 +393,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
                                }
                        }
 
+                       // Delete sector if we emptied it
                        if (all_blocks_deleted) {
                                sector_deletion_queue.push_back(sector_it.first);
                        }
@@ -408,6 +412,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
                        }
                }
                block_count_all = mapblock_queue.size();
+
                // Delete old blocks, and blocks over the limit from the memory
                while (!mapblock_queue.empty() && (mapblock_queue.size() > max_loaded_blocks
                                || mapblock_queue.top().block->getUsageTimer() > unload_timeout)) {
@@ -438,6 +443,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
                        deleted_blocks_count++;
                        block_count_all--;
                }
+
                // Delete empty sectors
                for (auto &sector_it : m_sectors) {
                        if (sector_it.second->empty()) {
@@ -445,7 +451,11 @@ void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
                        }
                }
        }
+
        endSave();
+       const auto end_time = porting::getTimeUs();
+
+       reportMetrics(end_time - start_time, saved_blocks_count, block_count_all);
 
        // Finally delete the empty sectors
        deleteSectors(sector_deletion_queue);
@@ -524,11 +534,11 @@ struct NodeNeighbor {
        { }
 };
 
-void Map::transforming_liquid_add(v3s16 p) {
+void ServerMap::transforming_liquid_add(v3s16 p) {
         m_transforming_liquid.push_back(p);
 }
 
-void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
+void ServerMap::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
                ServerEnvironment *env)
 {
        u32 loopcount = 0;
@@ -1231,7 +1241,12 @@ ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef,
        m_savedir = savedir;
        m_map_saving_enabled = false;
 
-       m_save_time_counter = mb->addCounter("minetest_core_map_save_time", "Map save time (in nanoseconds)");
+       m_save_time_counter = mb->addCounter(
+               "minetest_map_save_time", "Time spent saving blocks (in microseconds)");
+       m_save_count_counter = mb->addCounter(
+               "minetest_map_saved_blocks", "Number of blocks saved");
+       m_loaded_blocks_gauge = mb->addGauge(
+               "minetest_map_loaded_blocks", "Number of loaded blocks");
 
        m_map_compression_level = rangelim(g_settings->getS16("map_compression_level_disk"), -1, 9);
 
@@ -1466,11 +1481,7 @@ MapSector *ServerMap::createSector(v2s16 p2d)
        /*
                Do not create over max mapgen limit
        */
-       const s16 max_limit_bp = MAX_MAP_GENERATION_LIMIT / MAP_BLOCKSIZE;
-       if (p2d.X < -max_limit_bp ||
-                       p2d.X >  max_limit_bp ||
-                       p2d.Y < -max_limit_bp ||
-                       p2d.Y >  max_limit_bp)
+       if (blockpos_over_max_limit(v3s16(p2d.X, 0, p2d.Y)))
                throw InvalidPositionException("createSector(): pos. over max mapgen limit");
 
        /*
@@ -1479,9 +1490,6 @@ MapSector *ServerMap::createSector(v2s16 p2d)
 
        sector = new MapSector(this, p2d, m_gamedef);
 
-       // Sector position on map in nodes
-       //v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
-
        /*
                Insert to container
        */
@@ -1569,6 +1577,29 @@ bool ServerMap::isBlockInQueue(v3s16 pos)
        return m_emerge && m_emerge->isBlockInQueue(pos);
 }
 
+void ServerMap::addNodeAndUpdate(v3s16 p, MapNode n,
+               std::map<v3s16, MapBlock*> &modified_blocks,
+               bool remove_metadata)
+{
+       Map::addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
+
+       /*
+               Add neighboring liquid nodes and this node to transform queue.
+               (it's vital for the node itself to get updated last, if it was removed.)
+        */
+
+       for (const v3s16 &dir : g_7dirs) {
+               v3s16 p2 = p + dir;
+
+               bool is_valid_position;
+               MapNode n2 = getNode(p2, &is_valid_position);
+               if(is_valid_position &&
+                               (m_nodedef->get(n2).isLiquid() ||
+                               n2.getContent() == CONTENT_AIR))
+                       m_transforming_liquid.push_back(p2);
+       }
+}
+
 // N.B.  This requires no synchronization, since data will not be modified unless
 // the VoxelManipulator being updated belongs to the same thread.
 void ServerMap::updateVManip(v3s16 pos)
@@ -1591,6 +1622,13 @@ void ServerMap::updateVManip(v3s16 pos)
        vm->m_is_dirty = true;
 }
 
+void ServerMap::reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks)
+{
+       m_loaded_blocks_gauge->set(all_blocks);
+       m_save_time_counter->increment(save_time_us);
+       m_save_count_counter->increment(saved_blocks);
+}
+
 void ServerMap::save(ModifiedState save_level)
 {
        if (!m_map_saving_enabled) {
@@ -1598,7 +1636,7 @@ void ServerMap::save(ModifiedState save_level)
                return;
        }
 
-       u64 start_time = porting::getTimeNs();
+       const auto start_time = porting::getTimeUs();
 
        if(save_level == MOD_STATE_CLEAN)
                infostream<<"ServerMap: Saving whole map, this can take time."
@@ -1659,8 +1697,8 @@ void ServerMap::save(ModifiedState save_level)
                modprofiler.print(infostream);
        }
 
-       auto end_time = porting::getTimeNs();
-       m_save_time_counter->increment(end_time - start_time);
+       const auto end_time = porting::getTimeUs();
+       reportMetrics(end_time - start_time, block_count, block_count_all);
 }
 
 void ServerMap::listAllLoadableBlocks(std::vector<v3s16> &dst)
@@ -1878,6 +1916,7 @@ MMVManip::MMVManip(Map *map):
                VoxelManipulator(),
                m_map(map)
 {
+       assert(map);
 }
 
 void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
@@ -1885,6 +1924,8 @@ void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
 {
        TimeTaker timer1("initialEmerge", &emerge_time);
 
+       assert(m_map);
+
        // Units of these are MapBlocks
        v3s16 p_min = blockpos_min;
        v3s16 p_max = blockpos_max;
@@ -1968,6 +2009,7 @@ void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
 {
        if(m_area.getExtent() == v3s16(0,0,0))
                return;
+       assert(m_map);
 
        /*
                Copy data of all blocks
@@ -1988,4 +2030,33 @@ void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
        }
 }
 
+MMVManip *MMVManip::clone() const
+{
+       MMVManip *ret = new MMVManip();
+
+       const s32 size = m_area.getVolume();
+       ret->m_area = m_area;
+       if (m_data) {
+               ret->m_data = new MapNode[size];
+               memcpy(ret->m_data, m_data, size * sizeof(MapNode));
+       }
+       if (m_flags) {
+               ret->m_flags = new u8[size];
+               memcpy(ret->m_flags, m_flags, size * sizeof(u8));
+       }
+
+       ret->m_is_dirty = m_is_dirty;
+       // Even if the copy is disconnected from a map object keep the information
+       // needed to write it back to one
+       ret->m_loaded_blocks = m_loaded_blocks;
+
+       return ret;
+}
+
+void MMVManip::reparent(Map *map)
+{
+       assert(map && !m_map);
+       m_map = map;
+}
+
 //END
index 9c5c16368b1e98e39074179ecaba9f40a6751c13..248312ebe5436d3f6539fe949ed9931b808583b9 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -54,10 +54,6 @@ struct BlockMakeData;
        MapEditEvent
 */
 
-#define MAPTYPE_BASE 0
-#define MAPTYPE_SERVER 1
-#define MAPTYPE_CLIENT 2
-
 enum MapEditEventType{
        // Node added (changed from air or something else to something)
        MEET_ADDNODE,
@@ -127,11 +123,6 @@ class Map /*: public NodeContainer*/
        virtual ~Map();
        DISABLE_CLASS_COPY(Map);
 
-       virtual s32 mapType() const
-       {
-               return MAPTYPE_BASE;
-       }
-
        /*
                Drop (client) or delete (server) the map.
        */
@@ -169,9 +160,6 @@ class Map /*: public NodeContainer*/
 
        inline const NodeDefManager * getNodeDefManager() { return m_nodedef; }
 
-       // Returns InvalidPositionException if not found
-       bool isNodeUnderground(v3s16 p);
-
        bool isValidPosition(v3s16 p);
 
        // throws InvalidPositionException if not found
@@ -185,7 +173,7 @@ class Map /*: public NodeContainer*/
        /*
                These handle lighting but not faces.
        */
-       void addNodeAndUpdate(v3s16 p, MapNode n,
+       virtual void addNodeAndUpdate(v3s16 p, MapNode n,
                        std::map<v3s16, MapBlock*> &modified_blocks,
                        bool remove_metadata = true);
        void removeNodeAndUpdate(v3s16 p,
@@ -205,6 +193,11 @@ class Map /*: public NodeContainer*/
 
        virtual void save(ModifiedState save_level) { FATAL_ERROR("FIXME"); }
 
+       /*
+               Return true unless the map definitely cannot save blocks.
+       */
+       virtual bool maySaveBlocks() { return true; }
+
        // Server implements these.
        // Client leaves them as no-op.
        virtual bool saveBlock(MapBlock *block) { return false; }
@@ -212,14 +205,14 @@ class Map /*: public NodeContainer*/
 
        /*
                Updates usage timers and unloads unused blocks and sectors.
-               Saves modified blocks before unloading on MAPTYPE_SERVER.
+               Saves modified blocks before unloading if possible.
        */
        void timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
                        std::vector<v3s16> *unloaded_blocks=NULL);
 
        /*
                Unloads all blocks with a zero refCount().
-               Saves modified blocks before unloading on MAPTYPE_SERVER.
+               Saves modified blocks before unloading if possible.
        */
        void unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks=NULL);
 
@@ -231,9 +224,6 @@ class Map /*: public NodeContainer*/
        // For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
        virtual void PrintInfo(std::ostream &out);
 
-       void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks,
-                       ServerEnvironment *env);
-
        /*
                Node metadata
                These are basically coordinate wrappers to MapBlock
@@ -272,12 +262,8 @@ class Map /*: public NodeContainer*/
                Variables
        */
 
-       void transforming_liquid_add(v3s16 p);
-
        bool isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes);
 protected:
-       friend class LuaVoxelManip;
-
        IGameDef *m_gamedef;
 
        std::set<MapEventReceiver*> m_event_receivers;
@@ -288,23 +274,17 @@ class Map /*: public NodeContainer*/
        MapSector *m_sector_cache = nullptr;
        v2s16 m_sector_cache_p;
 
-       // Queued transforming water nodes
-       UniqueQueue<v3s16> m_transforming_liquid;
-
        // This stores the properties of the nodes on the map.
        const NodeDefManager *m_nodedef;
 
+       // Can be implemented by child class
+       virtual void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) {}
+
        bool determineAdditionalOcclusionCheck(const v3s16 &pos_camera,
                const core::aabbox3d<s16> &block_bounds, v3s16 &check);
        bool isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
                float step, float stepfac, float start_offset, float end_offset,
                u32 needed_count);
-
-private:
-       f32 m_transforming_liquid_loop_count_multiplier = 1.0f;
-       u32 m_unprocessed_count = 0;
-       u64 m_inc_trending_up_start_time = 0; // milliseconds
-       bool m_queue_size_timer_started = false;
 };
 
 /*
@@ -322,11 +302,6 @@ class ServerMap : public Map
        ServerMap(const std::string &savedir, IGameDef *gamedef, EmergeManager *emerge, MetricsBackend *mb);
        ~ServerMap();
 
-       s32 mapType() const
-       {
-               return MAPTYPE_SERVER;
-       }
-
        /*
                Get a sector from somewhere.
                - Check memory
@@ -357,7 +332,7 @@ class ServerMap : public Map
                - Create blank filled with CONTENT_IGNORE
 
        */
-       MapBlock *emergeBlock(v3s16 p, bool create_blank=true);
+       MapBlock *emergeBlock(v3s16 p, bool create_blank=true) override;
 
        /*
                Try to get a block.
@@ -369,32 +344,36 @@ class ServerMap : public Map
 
        bool isBlockInQueue(v3s16 pos);
 
+       void addNodeAndUpdate(v3s16 p, MapNode n,
+                       std::map<v3s16, MapBlock*> &modified_blocks,
+                       bool remove_metadata) override;
+
        /*
                Database functions
        */
        static MapDatabase *createDatabase(const std::string &name, const std::string &savedir, Settings &conf);
 
        // Call these before and after saving of blocks
-       void beginSave();
-       void endSave();
+       void beginSave() override;
+       void endSave() override;
 
-       void save(ModifiedState save_level);
+       void save(ModifiedState save_level) override;
        void listAllLoadableBlocks(std::vector<v3s16> &dst);
 
        MapgenParams *getMapgenParams();
 
-       bool saveBlock(MapBlock *block);
+       bool saveBlock(MapBlock *block) override;
        static bool saveBlock(MapBlock *block, MapDatabase *db, int compression_level = -1);
        MapBlock* loadBlock(v3s16 p);
        // Database version
        void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
 
-       bool deleteBlock(v3s16 blockpos);
+       bool deleteBlock(v3s16 blockpos) override;
 
        void updateVManip(v3s16 pos);
 
        // For debug printing
-       virtual void PrintInfo(std::ostream &out);
+       void PrintInfo(std::ostream &out) override;
 
        bool isSavingEnabled(){ return m_map_saving_enabled; }
 
@@ -410,9 +389,20 @@ class ServerMap : public Map
        bool repairBlockLight(v3s16 blockpos,
                std::map<v3s16, MapBlock *> *modified_blocks);
 
+       void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks,
+                       ServerEnvironment *env);
+
+       void transforming_liquid_add(v3s16 p);
+
        MapSettingsManager settings_mgr;
 
+protected:
+
+       void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) override;
+
 private:
+       friend class LuaVoxelManip;
+
        // Emerge manager
        EmergeManager *m_emerge;
 
@@ -423,6 +413,13 @@ class ServerMap : public Map
 
        std::set<v3s16> m_chunks_in_progress;
 
+       // Queued transforming water nodes
+       UniqueQueue<v3s16> m_transforming_liquid;
+       f32 m_transforming_liquid_loop_count_multiplier = 1.0f;
+       u32 m_unprocessed_count = 0;
+       u64 m_inc_trending_up_start_time = 0; // milliseconds
+       bool m_queue_size_timer_started = false;
+
        /*
                Metadata is re-written on disk only if this is true.
                This is reset to false when written on disk.
@@ -431,7 +428,10 @@ class ServerMap : public Map
        MapDatabase *dbase = nullptr;
        MapDatabase *dbase_ro = nullptr;
 
+       // Map metrics
+       MetricGaugePtr m_loaded_blocks_gauge;
        MetricCounterPtr m_save_time_counter;
+       MetricCounterPtr m_save_count_counter;
 };
 
 
@@ -457,10 +457,25 @@ class MMVManip : public VoxelManipulator
        void blitBackAll(std::map<v3s16, MapBlock*> * modified_blocks,
                bool overwrite_generated = true);
 
+       /*
+               Creates a copy of this VManip including contents, the copy will not be
+               associated with a Map.
+       */
+       MMVManip *clone() const;
+
+       // Reassociates a copied VManip to a map
+       void reparent(Map *map);
+
+       // Is it impossible to call initialEmerge / blitBackAll?
+       inline bool isOrphan() const { return !m_map; }
+
        bool m_is_dirty = false;
 
 protected:
-       Map *m_map;
+       MMVManip() {};
+
+       // may be null
+       Map *m_map = nullptr;
        /*
                key = blockpos
                value = flags describing the block
index 7e86a99379153e9e85c0b7305122ee39bf1f153b..c75483edb4cc96db5450a29c4391ec9d0133c0bd 100644 (file)
@@ -52,14 +52,7 @@ MapSettingsManager::~MapSettingsManager()
 bool MapSettingsManager::getMapSetting(
        const std::string &name, std::string *value_out)
 {
-       // Try getting it normally first
-       if (m_map_settings->getNoEx(name, *value_out))
-               return true;
-
-       // If not we may have to resolve some compatibility kludges
-       if (name == "seed")
-               return Settings::getLayer(SL_GLOBAL)->getNoEx("fixed_map_seed", *value_out);
-       return false;
+       return m_map_settings->getNoEx(name, *value_out);
 }
 
 
index 4958d3a65a36ca2bcfed0d1bc72e2836d21d1b4e..e3a6caa199616f6e416e1dc2c044dea12e1a0c17 100644 (file)
@@ -218,31 +218,6 @@ void MapBlock::expireDayNightDiff()
        m_day_night_differs_expired = true;
 }
 
-s16 MapBlock::getGroundLevel(v2s16 p2d)
-{
-       if(isDummy())
-               return -3;
-       try
-       {
-               s16 y = MAP_BLOCKSIZE-1;
-               for(; y>=0; y--)
-               {
-                       MapNode n = getNodeRef(p2d.X, y, p2d.Y);
-                       if (m_gamedef->ndef()->get(n).walkable) {
-                               if(y == MAP_BLOCKSIZE-1)
-                                       return -2;
-
-                               return y;
-                       }
-               }
-               return -1;
-       }
-       catch(InvalidPositionException &e)
-       {
-               return -3;
-       }
-}
-
 /*
        Serialization
 */
index 8de631a2925fbae3f6537d6daf2e3733ffb96f58..a86db7b70fd1115511055c9a4d9549d949910eee 100644 (file)
@@ -363,20 +363,6 @@ class MapBlock
                return m_day_night_differs;
        }
 
-       ////
-       //// Miscellaneous stuff
-       ////
-
-       /*
-               Tries to measure ground level.
-               Return value:
-                       -1 = only air
-                       -2 = only ground
-                       -3 = random fail
-                       0...MAP_BLOCKSIZE-1 = ground level
-       */
-       s16 getGroundLevel(v2s16 p2d);
-
        ////
        //// Timestamp (see m_timestamp)
        ////
@@ -615,7 +601,7 @@ typedef std::vector<MapBlock*> MapBlockVect;
 
 inline bool objectpos_over_limit(v3f p)
 {
-       const float max_limit_bs = MAX_MAP_GENERATION_LIMIT * BS;
+       const float max_limit_bs = (MAX_MAP_GENERATION_LIMIT + 0.5f) * BS;
        return p.X < -max_limit_bs ||
                p.X >  max_limit_bs ||
                p.Y < -max_limit_bs ||
index acdb1a0f0f27edd0348f5cf8b72d6f2f4563e4de..1d439abebddb9afe533e627cab91248e8106b0c5 100644 (file)
@@ -71,7 +71,7 @@ DungeonGen::DungeonGen(const NodeDefManager *ndef,
                dp.num_dungeons        = 1;
                dp.notifytype          = GENNOTIFY_DUNGEON;
 
-               dp.np_alt_wall = 
+               dp.np_alt_wall =
                        NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0);
        }
 }
index 7984ff609287031d86c7adef5454b5147f62108d..d767bd264dd350b8741842581ed4719ada575e64 100644 (file)
@@ -1018,10 +1018,11 @@ MapgenParams::~MapgenParams()
 
 void MapgenParams::readParams(const Settings *settings)
 {
-       std::string seed_str;
-       const char *seed_name = (settings == g_settings) ? "fixed_map_seed" : "seed";
+       // should always be used via MapSettingsManager
+       assert(settings != g_settings);
 
-       if (settings->getNoEx(seed_name, seed_str)) {
+       std::string seed_str;
+       if (settings->getNoEx("seed", seed_str)) {
                if (!seed_str.empty())
                        seed = read_seed(seed_str.c_str());
                else
index 342455029189871bf0ad56c94cd5cc488f8b350e..6b249ea1fe239d1b75ec8eadba8d93af67e3d9bf 100644 (file)
@@ -177,7 +177,7 @@ void MapgenFlatParams::setDefaultSettings(Settings *settings)
 int MapgenFlat::getSpawnLevelAtPoint(v2s16 p)
 {
        s16 stone_level = ground_level;
-       float n_terrain = 
+       float n_terrain =
                ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) ?
                NoisePerlin2D(&noise_terrain->np, p.X, p.Y, seed) :
                0.0f;
index bce9cee8123100f14e208dcfc2037fc0fc2f06be..a418acaceae0001fae5b85f124474997bad58b0a 100644 (file)
@@ -360,19 +360,6 @@ int MapgenV6::getSpawnLevelAtPoint(v2s16 p)
 
 //////////////////////// Noise functions
 
-float MapgenV6::getMudAmount(v2s16 p)
-{
-       int index = (p.Y - node_min.Z) * ystride + (p.X - node_min.X);
-       return getMudAmount(index);
-}
-
-
-bool MapgenV6::getHaveBeach(v2s16 p)
-{
-       int index = (p.Y - node_min.Z) * ystride + (p.X - node_min.X);
-       return getHaveBeach(index);
-}
-
 
 BiomeV6Type MapgenV6::getBiome(v2s16 p)
 {
index a6e6da8c6ea8acdcb2b2f4dd9ebf8b77af3fbce3..b0eb67893c7e6f865640806c483f7df0feb74b88 100644 (file)
@@ -154,9 +154,7 @@ class MapgenV6 : public Mapgen {
        float getHumidity(v2s16 p);
        float getTreeAmount(v2s16 p);
        bool getHaveAppleTree(v2s16 p);
-       float getMudAmount(v2s16 p);
-       virtual float getMudAmount(int index);
-       bool getHaveBeach(v2s16 p);
+       float getMudAmount(int index);
        bool getHaveBeach(int index);
        BiomeV6Type getBiome(v2s16 p);
        BiomeV6Type getBiome(int index, v2s16 p);
index f08cc190f71e3258afec47bd08ca2228a177d6f3..8b4c96cd5cdc47be0322e79c8815abac1f7deaf8 100644 (file)
@@ -273,7 +273,7 @@ Biome *BiomeGenOriginal::calcBiomeFromNoise(float heat, float humidity, v3s16 po
                        pos.Y - biome_closest_blend->max_pos.Y)
                return biome_closest_blend;
 
-       return (biome_closest) ? biome_closest : (Biome *)m_bmgr->getRaw(BIOME_NONE);   
+       return (biome_closest) ? biome_closest : (Biome *)m_bmgr->getRaw(BIOME_NONE);
 }
 
 
index 5814f433a81182b7214aeb15f6637f36b4d0b5a2..4f0c35548454516727f2033bd89275f8cf4d56a7 100644 (file)
@@ -498,8 +498,8 @@ void OreVein::generate(MMVManip *vm, int mapseed, u32 blockseed,
                }
 
                // randval ranges from -1..1
-               /* 
-                       Note: can generate values slightly larger than 1 
+               /*
+                       Note: can generate values slightly larger than 1
                        but this can't be changed as mapgen must be deterministic accross versions.
                */
                float randval   = (float)pr.next() / float(pr.RANDOM_RANGE / 2) - 1.f;
index 301dcb0923c6bd47a6c454bd030426873c18471a..9626e8e0c4250962cc0b8b0378b8c9e23dfe9a4c 100644 (file)
@@ -88,8 +88,7 @@ bool ModChannelMgr::canWriteOnChannel(const std::string &channel) const
 
 void ModChannelMgr::registerChannel(const std::string &channel)
 {
-       m_registered_channels[channel] =
-                       std::unique_ptr<ModChannel>(new ModChannel(channel));
+       m_registered_channels[channel] = std::make_unique<ModChannel>(channel);
 }
 
 bool ModChannelMgr::setChannelState(const std::string &channel, ModChannelState state)
index 05678aa62cc865a2fb8c46a623a5b5b857e1cc84..cf2e6208db5326c3ef186dadf5c5997eae97de00 100644 (file)
@@ -87,38 +87,31 @@ Address::Address(const IPv6AddressBytes *ipv6_bytes, u16 port)
        setPort(port);
 }
 
-// Equality (address family, address and port must be equal)
-bool Address::operator==(const Address &address)
+// Equality (address family, IP and port must be equal)
+bool Address::operator==(const Address &other)
 {
-       if (address.m_addr_family != m_addr_family || address.m_port != m_port)
+       if (other.m_addr_family != m_addr_family || other.m_port != m_port)
                return false;
 
        if (m_addr_family == AF_INET) {
-               return m_address.ipv4.sin_addr.s_addr ==
-                      address.m_address.ipv4.sin_addr.s_addr;
+               return m_address.ipv4.s_addr == other.m_address.ipv4.s_addr;
        }
 
        if (m_addr_family == AF_INET6) {
-               return memcmp(m_address.ipv6.sin6_addr.s6_addr,
-                                      address.m_address.ipv6.sin6_addr.s6_addr, 16) == 0;
+               return memcmp(m_address.ipv6.s6_addr,
+                               other.m_address.ipv6.s6_addr, 16) == 0;
        }
 
        return false;
 }
 
-bool Address::operator!=(const Address &address)
-{
-       return !(*this == address);
-}
-
 void Address::Resolve(const char *name)
 {
        if (!name || name[0] == 0) {
-               if (m_addr_family == AF_INET) {
-                       setAddress((u32)0);
-               } else if (m_addr_family == AF_INET6) {
-                       setAddress((IPv6AddressBytes *)0);
-               }
+               if (m_addr_family == AF_INET)
+                       setAddress(static_cast<u32>(0));
+               else if (m_addr_family == AF_INET6)
+                       setAddress(static_cast<IPv6AddressBytes*>(nullptr));
                return;
        }
 
@@ -126,9 +119,6 @@ void Address::Resolve(const char *name)
        memset(&hints, 0, sizeof(hints));
 
        // Setup hints
-       hints.ai_socktype = 0;
-       hints.ai_protocol = 0;
-       hints.ai_flags = 0;
        if (g_settings->getBool("enable_ipv6")) {
                // AF_UNSPEC allows both IPv6 and IPv4 addresses to be returned
                hints.ai_family = AF_UNSPEC;
@@ -145,14 +135,13 @@ void Address::Resolve(const char *name)
        if (resolved->ai_family == AF_INET) {
                struct sockaddr_in *t = (struct sockaddr_in *)resolved->ai_addr;
                m_addr_family = AF_INET;
-               m_address.ipv4 = *t;
+               m_address.ipv4 = t->sin_addr;
        } else if (resolved->ai_family == AF_INET6) {
                struct sockaddr_in6 *t = (struct sockaddr_in6 *)resolved->ai_addr;
                m_addr_family = AF_INET6;
-               m_address.ipv6 = *t;
+               m_address.ipv6 = t->sin6_addr;
        } else {
-               freeaddrinfo(resolved);
-               throw ResolveError("");
+               m_addr_family = 0;
        }
        freeaddrinfo(resolved);
 }
@@ -163,47 +152,37 @@ std::string Address::serializeString() const
 // windows XP doesnt have inet_ntop, maybe use better func
 #ifdef _WIN32
        if (m_addr_family == AF_INET) {
-               u8 a, b, c, d;
-               u32 addr;
-               addr = ntohl(m_address.ipv4.sin_addr.s_addr);
-               a = (addr & 0xFF000000) >> 24;
-               b = (addr & 0x00FF0000) >> 16;
-               c = (addr & 0x0000FF00) >> 8;
-               d = (addr & 0x000000FF);
-               return itos(a) + "." + itos(b) + "." + itos(c) + "." + itos(d);
+               return inet_ntoa(m_address.ipv4);
        } else if (m_addr_family == AF_INET6) {
                std::ostringstream os;
+               os << std::hex;
                for (int i = 0; i < 16; i += 2) {
-                       u16 section = (m_address.ipv6.sin6_addr.s6_addr[i] << 8) |
-                                     (m_address.ipv6.sin6_addr.s6_addr[i + 1]);
-                       os << std::hex << section;
+                       u16 section = (m_address.ipv6.s6_addr[i] << 8) |
+                                       (m_address.ipv6.s6_addr[i + 1]);
+                       os << section;
                        if (i < 14)
                                os << ":";
                }
                return os.str();
-       } else
-               return std::string("");
+       } else {
+               return "";
+       }
 #else
        char str[INET6_ADDRSTRLEN];
-       if (inet_ntop(m_addr_family,
-                           (m_addr_family == AF_INET)
-                                           ? (void *)&(m_address.ipv4.sin_addr)
-                                           : (void *)&(m_address.ipv6.sin6_addr),
-                           str, INET6_ADDRSTRLEN) == NULL) {
-               return std::string("");
-       }
-       return std::string(str);
+       if (inet_ntop(m_addr_family, (void*) &m_address, str, sizeof(str)) == nullptr)
+               return "";
+       return str;
 #endif
 }
 
-struct sockaddr_in Address::getAddress() const
+struct in_addr Address::getAddress() const
 {
-       return m_address.ipv4; // NOTE: NO PORT INCLUDED, use getPort()
+       return m_address.ipv4;
 }
 
-struct sockaddr_in6 Address::getAddress6() const
+struct in6_addr Address::getAddress6() const
 {
-       return m_address.ipv6; // NOTE: NO PORT INCLUDED, use getPort()
+       return m_address.ipv6;
 }
 
 u16 Address::getPort() const
@@ -211,52 +190,39 @@ u16 Address::getPort() const
        return m_port;
 }
 
-int Address::getFamily() const
-{
-       return m_addr_family;
-}
-
-bool Address::isIPv6() const
-{
-       return m_addr_family == AF_INET6;
-}
-
 bool Address::isZero() const
 {
        if (m_addr_family == AF_INET) {
-               return m_address.ipv4.sin_addr.s_addr == 0;
+               return m_address.ipv4.s_addr == 0;
        }
 
        if (m_addr_family == AF_INET6) {
                static const char zero[16] = {0};
-               return memcmp(m_address.ipv6.sin6_addr.s6_addr, zero, 16) == 0;
+               return memcmp(m_address.ipv6.s6_addr, zero, 16) == 0;
        }
+
        return false;
 }
 
 void Address::setAddress(u32 address)
 {
        m_addr_family = AF_INET;
-       m_address.ipv4.sin_family = AF_INET;
-       m_address.ipv4.sin_addr.s_addr = htonl(address);
+       m_address.ipv4.s_addr = htonl(address);
 }
 
 void Address::setAddress(u8 a, u8 b, u8 c, u8 d)
 {
-       m_addr_family = AF_INET;
-       m_address.ipv4.sin_family = AF_INET;
-       u32 addr = htonl((a << 24) | (b << 16) | (c << 8) | d);
-       m_address.ipv4.sin_addr.s_addr = addr;
+       u32 addr = (a << 24) | (b << 16) | (c << 8) | d;
+       setAddress(addr);
 }
 
 void Address::setAddress(const IPv6AddressBytes *ipv6_bytes)
 {
        m_addr_family = AF_INET6;
-       m_address.ipv6.sin6_family = AF_INET6;
        if (ipv6_bytes)
-               memcpy(m_address.ipv6.sin6_addr.s6_addr, ipv6_bytes->bytes, 16);
+               memcpy(m_address.ipv6.s6_addr, ipv6_bytes->bytes, 16);
        else
-               memset(m_address.ipv6.sin6_addr.s6_addr, 0, 16);
+               memset(m_address.ipv6.s6_addr, 0, 16);
 }
 
 void Address::setPort(u16 port)
@@ -264,27 +230,30 @@ void Address::setPort(u16 port)
        m_port = port;
 }
 
-void Address::print(std::ostream *s) const
+void Address::print(std::ostreams) const
 {
        if (m_addr_family == AF_INET6)
-               *s << "[" << serializeString() << "]:" << m_port;
+               s << "[" << serializeString() << "]:" << m_port;
+       else if (m_addr_family == AF_INET)
+               s << serializeString() << ":" << m_port;
        else
-               *s << serializeString() << ":" << m_port;
+               s << "(undefined)";
 }
 
 bool Address::isLocalhost() const
 {
        if (isIPv6()) {
-               static const unsigned char localhost_bytes[] = {
+               static const u8 localhost_bytes[] = {
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-               static const unsigned char mapped_ipv4_localhost[] = {
+               static const u8 mapped_ipv4_localhost[] = {
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 0};
 
-               auto addr = m_address.ipv6.sin6_addr.s6_addr;
+               auto addr = m_address.ipv6.s6_addr;
 
                return memcmp(addr, localhost_bytes, 16) == 0 ||
                        memcmp(addr, mapped_ipv4_localhost, 13) == 0;
        }
 
-       return (m_address.ipv4.sin_addr.s_addr & 0xFF) == 0x7f;
+       auto addr = ntohl(m_address.ipv4.s_addr);
+       return (addr >> 24) == 0x7f;
 }
index 4329c84a84e8973eed4d5d433c2237e64444069f..692bf82c53a6687e2df403076c756c2ea34e37df 100644 (file)
@@ -36,9 +36,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes.h"
 #include "networkexceptions.h"
 
-class IPv6AddressBytes
+struct IPv6AddressBytes
 {
-public:
        u8 bytes[16];
        IPv6AddressBytes() { memset(bytes, 0, 16); }
 };
@@ -50,30 +49,34 @@ class Address
        Address(u32 address, u16 port);
        Address(u8 a, u8 b, u8 c, u8 d, u16 port);
        Address(const IPv6AddressBytes *ipv6_bytes, u16 port);
+
        bool operator==(const Address &address);
-       bool operator!=(const Address &address);
+       bool operator!=(const Address &address) { return !(*this == address); }
+
+       struct in_addr getAddress() const;
+       struct in6_addr getAddress6() const;
+       u16 getPort() const;
+       int getFamily() const { return m_addr_family; }
+       bool isIPv6() const { return m_addr_family == AF_INET6; }
+       bool isZero() const;
+       void print(std::ostream &s) const;
+       std::string serializeString() const;
+       bool isLocalhost() const;
+
        // Resolve() may throw ResolveError (address is unchanged in this case)
        void Resolve(const char *name);
-       struct sockaddr_in getAddress() const;
-       unsigned short getPort() const;
+
        void setAddress(u32 address);
        void setAddress(u8 a, u8 b, u8 c, u8 d);
        void setAddress(const IPv6AddressBytes *ipv6_bytes);
-       struct sockaddr_in6 getAddress6() const;
-       int getFamily() const;
-       bool isIPv6() const;
-       bool isZero() const;
-       void setPort(unsigned short port);
-       void print(std::ostream *s) const;
-       std::string serializeString() const;
-       bool isLocalhost() const;
+       void setPort(u16 port);
 
 private:
-       unsigned int m_addr_family = 0;
+       unsigned short m_addr_family = 0;
        union
        {
-               struct sockaddr_in ipv4;
-               struct sockaddr_in6 ipv6;
+               struct in_addr ipv4;
+               struct in6_addr ipv6;
        } m_address;
        u16 m_port = 0; // Port is separate from sockaddr structures
 };
index a98a5e7d187b00b0bc31d5d6aeec5534862c3a1e..6a78b4652e072fb030babce62acf3322176e7826 100644 (file)
@@ -123,6 +123,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
        { "TOCLIENT_SRP_BYTES_S_B",            TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_SrpBytesSandB }, // 0x60
        { "TOCLIENT_FORMSPEC_PREPEND",         TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FormspecPrepend }, // 0x61,
        { "TOCLIENT_MINIMAP_MODES",            TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MinimapModes }, // 0x62,
+       { "TOCLIENT_SET_LIGHTING",        TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SetLighting }, // 0x63,
 };
 
 const static ServerCommandFactory null_command_factory = { "TOSERVER_NULL", 0, false };
index 6497bb26a92f5ad65aa1d13979ff00131a7621fb..29e3364db0e2d6ef4a50b365832076702820c0be 100644 (file)
@@ -45,6 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "tileanimation.h"
 #include "gettext.h"
 #include "skyparams.h"
+#include <memory>
 
 void Client::handleCommand_Deprecated(NetworkPacket* pkt)
 {
@@ -184,7 +185,7 @@ void Client::handleCommand_AccessDenied(NetworkPacket* pkt)
        m_access_denied_reason = "Unknown";
 
        if (pkt->getCommand() != TOCLIENT_ACCESS_DENIED) {
-               // 13/03/15 Legacy code from 0.4.12 and lesser but is still used
+               // Legacy code from 0.4.12 and older but is still used
                // in some places of the server code
                if (pkt->getSize() >= 2) {
                        std::wstring wide_reason;
@@ -197,14 +198,14 @@ void Client::handleCommand_AccessDenied(NetworkPacket* pkt)
        if (pkt->getSize() < 1)
                return;
 
-       u8 denyCode = SERVER_ACCESSDENIED_UNEXPECTED_DATA;
+       u8 denyCode;
        *pkt >> denyCode;
+
        if (denyCode == SERVER_ACCESSDENIED_SHUTDOWN ||
                        denyCode == SERVER_ACCESSDENIED_CRASH) {
                *pkt >> m_access_denied_reason;
-               if (m_access_denied_reason.empty()) {
+               if (m_access_denied_reason.empty())
                        m_access_denied_reason = accessDeniedStrings[denyCode];
-               }
                u8 reconnect;
                *pkt >> reconnect;
                m_access_denied_reconnect = reconnect & 1;
@@ -221,9 +222,8 @@ void Client::handleCommand_AccessDenied(NetworkPacket* pkt)
                // Until then (which may be never), this is outside
                // of the defined protocol.
                *pkt >> m_access_denied_reason;
-               if (m_access_denied_reason.empty()) {
+               if (m_access_denied_reason.empty())
                        m_access_denied_reason = "Unknown";
-               }
        }
 }
 
@@ -918,11 +918,6 @@ void Client::handleCommand_Privileges(NetworkPacket* pkt)
                m_privileges.insert(priv);
                infostream << priv << " ";
        }
-
-       // Enable basic_debug on server versions before it was added
-       if (m_proto_ver < 40)
-               m_privileges.insert("basic_debug");
-
        infostream << std::endl;
 }
 
@@ -1269,19 +1264,17 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
                } catch (...) {}
 
                // Use default skybox settings:
-               SkyboxDefaults sky_defaults;
-               SunParams sun = sky_defaults.getSunDefaults();
-               MoonParams moon = sky_defaults.getMoonDefaults();
-               StarParams stars = sky_defaults.getStarDefaults();
+               SunParams sun = SkyboxDefaults::getSunDefaults();
+               MoonParams moon = SkyboxDefaults::getMoonDefaults();
+               StarParams stars = SkyboxDefaults::getStarDefaults();
 
                // Fix for "regular" skies, as color isn't kept:
                if (skybox.type == "regular") {
-                       skybox.sky_color = sky_defaults.getSkyColorDefaults();
+                       skybox.sky_color = SkyboxDefaults::getSkyColorDefaults();
                        skybox.fog_tint_type = "default";
                        skybox.fog_moon_tint = video::SColor(255, 255, 255, 255);
                        skybox.fog_sun_tint = video::SColor(255, 255, 255, 255);
-               }
-               else {
+               } else {
                        sun.visible = false;
                        sun.sunrise_visible = false;
                        moon.visible = false;
@@ -1431,6 +1424,8 @@ void Client::handleCommand_LocalPlayerAnimations(NetworkPacket* pkt)
        *pkt >> player->local_animations[2];
        *pkt >> player->local_animations[3];
        *pkt >> player->local_animation_speed;
+
+       player->last_animation = -1;
 }
 
 void Client::handleCommand_EyeOffset(NetworkPacket* pkt)
@@ -1589,7 +1584,7 @@ void Client::handleCommand_MediaPush(NetworkPacket *pkt)
        m_media_pushed_files.insert(filename);
 
        // create a downloader for this file
-       auto downloader = new SingleMediaDownloader(cached);
+       auto downloader(std::make_shared<SingleMediaDownloader>(cached));
        m_pending_media_downloads.emplace_back(token, downloader);
        downloader->addFile(filename, raw_hash);
        for (const auto &baseurl : m_remote_media_servers)
@@ -1716,3 +1711,11 @@ void Client::handleCommand_MinimapModes(NetworkPacket *pkt)
        if (m_minimap)
                m_minimap->setModeIndex(mode);
 }
+
+void Client::handleCommand_SetLighting(NetworkPacket *pkt)
+{
+       Lighting& lighting = m_env.getLocalPlayer()->getLighting();
+
+       if (pkt->getRemainingBytes() >= 4)
+               *pkt >> lighting.shadow_intensity;
+}
index a4970954ffd1272313b7421d1e779452582db95e..6fb676f25c4fe30e8e23195dbc91d1fffa4ea84e 100644 (file)
@@ -41,39 +41,37 @@ namespace con
 /* defines used for debugging and profiling                                   */
 /******************************************************************************/
 #ifdef NDEBUG
-       #define LOG(a) a
        #define PROFILE(a)
 #else
-       #if 0
-       /* this mutex is used to achieve log message consistency */
-       std::mutex log_message_mutex;
-       #define LOG(a)                                                                 \
-               {                                                                          \
-               MutexAutoLock loglock(log_message_mutex);                                 \
-               a;                                                                         \
-               }
-       #else
-       // Prevent deadlocks until a solution is found after 5.2.0 (TODO)
-       #define LOG(a) a
-       #endif
-
        #define PROFILE(a) a
 #endif
 
+// TODO: Clean this up.
+#define LOG(a) a
+
 #define PING_TIMEOUT 5.0
 
-BufferedPacket makePacket(Address &address, const SharedBuffer<u8> &data,
+u16 BufferedPacket::getSeqnum() const
+{
+       if (size() < BASE_HEADER_SIZE + 3)
+               return 0; // should never happen
+
+       return readU16(&data[BASE_HEADER_SIZE + 1]);
+}
+
+BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data,
                u32 protocol_id, session_t sender_peer_id, u8 channel)
 {
        u32 packet_size = data.getSize() + BASE_HEADER_SIZE;
-       BufferedPacket p(packet_size);
-       p.address = address;
 
-       writeU32(&p.data[0], protocol_id);
-       writeU16(&p.data[4], sender_peer_id);
-       writeU8(&p.data[6], channel);
+       BufferedPacketPtr p(new BufferedPacket(packet_size));
+       p->address = address;
+
+       writeU32(&p->data[0], protocol_id);
+       writeU16(&p->data[4], sender_peer_id);
+       writeU8(&p->data[6], channel);
 
-       memcpy(&p.data[BASE_HEADER_SIZE], *data, data.getSize());
+       memcpy(&p->data[BASE_HEADER_SIZE], *data, data.getSize());
 
        return p;
 }
@@ -169,9 +167,8 @@ void ReliablePacketBuffer::print()
        MutexAutoLock listlock(m_list_mutex);
        LOG(dout_con<<"Dump of ReliablePacketBuffer:" << std::endl);
        unsigned int index = 0;
-       for (BufferedPacket &bufferedPacket : m_list) {
-               u16 s = readU16(&(bufferedPacket.data[BASE_HEADER_SIZE+1]));
-               LOG(dout_con<<index<< ":" << s << std::endl);
+       for (BufferedPacketPtr &packet : m_list) {
+               LOG(dout_con<<index<< ":" << packet->getSeqnum() << std::endl);
                index++;
        }
 }
@@ -188,16 +185,13 @@ u32 ReliablePacketBuffer::size()
        return m_list.size();
 }
 
-RPBSearchResult ReliablePacketBuffer::findPacket(u16 seqnum)
+RPBSearchResult ReliablePacketBuffer::findPacketNoLock(u16 seqnum)
 {
-       std::list<BufferedPacket>::iterator i = m_list.begin();
-       for(; i != m_list.end(); ++i)
-       {
-               u16 s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
-               if (s == seqnum)
-                       break;
+       for (auto it = m_list.begin(); it != m_list.end(); ++it) {
+               if ((*it)->getSeqnum() == seqnum)
+                       return it;
        }
-       return i;
+       return m_list.end();
 }
 
 bool ReliablePacketBuffer::getFirstSeqnum(u16& result)
@@ -205,54 +199,54 @@ bool ReliablePacketBuffer::getFirstSeqnum(u16& result)
        MutexAutoLock listlock(m_list_mutex);
        if (m_list.empty())
                return false;
-       const BufferedPacket &p = m_list.front();
-       result = readU16(&p.data[BASE_HEADER_SIZE + 1]);
+       result = m_list.front()->getSeqnum();
        return true;
 }
 
-BufferedPacket ReliablePacketBuffer::popFirst()
+BufferedPacketPtr ReliablePacketBuffer::popFirst()
 {
        MutexAutoLock listlock(m_list_mutex);
        if (m_list.empty())
                throw NotFoundException("Buffer is empty");
-       BufferedPacket p = std::move(m_list.front());
+
+       BufferedPacketPtr p(m_list.front());
        m_list.pop_front();
 
        if (m_list.empty()) {
                m_oldest_non_answered_ack = 0;
        } else {
-               m_oldest_non_answered_ack =
-                               readU16(&m_list.front().data[BASE_HEADER_SIZE + 1]);
+               m_oldest_non_answered_ack = m_list.front()->getSeqnum();
        }
        return p;
 }
 
-BufferedPacket ReliablePacketBuffer::popSeqnum(u16 seqnum)
+BufferedPacketPtr ReliablePacketBuffer::popSeqnum(u16 seqnum)
 {
        MutexAutoLock listlock(m_list_mutex);
-       RPBSearchResult r = findPacket(seqnum);
-       if (r == notFound()) {
+       RPBSearchResult r = findPacketNoLock(seqnum);
+       if (r == m_list.end()) {
                LOG(dout_con<<"Sequence number: " << seqnum
                                << " not found in reliable buffer"<<std::endl);
                throw NotFoundException("seqnum not found in buffer");
        }
-       BufferedPacket p = std::move(*r);
 
+       BufferedPacketPtr p(*r);
        m_list.erase(r);
 
        if (m_list.empty()) {
                m_oldest_non_answered_ack = 0;
        } else {
-               m_oldest_non_answered_ack =
-                               readU16(&m_list.front().data[BASE_HEADER_SIZE + 1]);
+               m_oldest_non_answered_ack = m_list.front()->getSeqnum();
        }
        return p;
 }
 
-void ReliablePacketBuffer::insert(const BufferedPacket &p, u16 next_expected)
+void ReliablePacketBuffer::insert(BufferedPacketPtr &p_ptr, u16 next_expected)
 {
        MutexAutoLock listlock(m_list_mutex);
-       if (p.data.getSize() < BASE_HEADER_SIZE + 3) {
+       const BufferedPacket &p = *p_ptr;
+
+       if (p.size() < BASE_HEADER_SIZE + 3) {
                errorstream << "ReliablePacketBuffer::insert(): Invalid data size for "
                        "reliable packet" << std::endl;
                return;
@@ -263,7 +257,7 @@ void ReliablePacketBuffer::insert(const BufferedPacket &p, u16 next_expected)
                        << std::endl;
                return;
        }
-       u16 seqnum = readU16(&p.data[BASE_HEADER_SIZE + 1]);
+       const u16 seqnum = p.getSeqnum();
 
        if (!seqnum_in_window(seqnum, next_expected, MAX_RELIABLE_WINDOW_SIZE)) {
                errorstream << "ReliablePacketBuffer::insert(): seqnum is outside of "
@@ -280,44 +274,44 @@ void ReliablePacketBuffer::insert(const BufferedPacket &p, u16 next_expected)
 
        // Find the right place for the packet and insert it there
        // If list is empty, just add it
-       if (m_list.empty())
-       {
-               m_list.push_back(p);
+       if (m_list.empty()) {
+               m_list.push_back(p_ptr);
                m_oldest_non_answered_ack = seqnum;
                // Done.
                return;
        }
 
        // Otherwise find the right place
-       std::list<BufferedPacket>::iterator i = m_list.begin();
+       auto it = m_list.begin();
        // Find the first packet in the list which has a higher seqnum
-       u16 s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
+       u16 s = (*it)->getSeqnum();
 
        /* case seqnum is smaller then next_expected seqnum */
        /* this is true e.g. on wrap around */
        if (seqnum < next_expected) {
-               while(((s < seqnum) || (s >= next_expected)) && (i != m_list.end())) {
-                       ++i;
-                       if (i != m_list.end())
-                               s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
+               while(((s < seqnum) || (s >= next_expected)) && (it != m_list.end())) {
+                       ++it;
+                       if (it != m_list.end())
+                               s = (*it)->getSeqnum();
                }
        }
        /* non wrap around case (at least for incoming and next_expected */
        else
        {
-               while(((s < seqnum) && (s >= next_expected)) && (i != m_list.end())) {
-                       ++i;
-                       if (i != m_list.end())
-                               s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
+               while(((s < seqnum) && (s >= next_expected)) && (it != m_list.end())) {
+                       ++it;
+                       if (it != m_list.end())
+                               s = (*it)->getSeqnum();
                }
        }
 
        if (s == seqnum) {
                /* nothing to do this seems to be a resent packet */
                /* for paranoia reason data should be compared */
+               auto &i = *it;
                if (
-                       (readU16(&(i->data[BASE_HEADER_SIZE+1])) != seqnum) ||
-                       (i->data.getSize() != p.data.getSize()) ||
+                       (i->getSeqnum() != seqnum) ||
+                       (i->size() != p.size()) ||
                        (i->address != p.address)
                        )
                {
@@ -325,51 +319,52 @@ void ReliablePacketBuffer::insert(const BufferedPacket &p, u16 next_expected)
                        fprintf(stderr,
                                        "Duplicated seqnum %d non matching packet detected:\n",
                                        seqnum);
-                       fprintf(stderr, "Old: seqnum: %05d size: %04d, address: %s\n",
-                                       readU16(&(i->data[BASE_HEADER_SIZE+1])),i->data.getSize(),
+                       fprintf(stderr, "Old: seqnum: %05d size: %04zu, address: %s\n",
+                                       i->getSeqnum(), i->size(),
                                        i->address.serializeString().c_str());
-                       fprintf(stderr, "New: seqnum: %05d size: %04u, address: %s\n",
-                                       readU16(&(p.data[BASE_HEADER_SIZE+1])),p.data.getSize(),
+                       fprintf(stderr, "New: seqnum: %05d size: %04zu, address: %s\n",
+                                       p.getSeqnum(), p.size(),
                                        p.address.serializeString().c_str());
                        throw IncomingDataCorruption("duplicated packet isn't same as original one");
                }
        }
        /* insert or push back */
-       else if (i != m_list.end()) {
-               m_list.insert(i, p);
+       else if (it != m_list.end()) {
+               m_list.insert(it, p_ptr);
        } else {
-               m_list.push_back(p);
+               m_list.push_back(p_ptr);
        }
 
        /* update last packet number */
-       m_oldest_non_answered_ack = readU16(&m_list.front().data[BASE_HEADER_SIZE+1]);
+       m_oldest_non_answered_ack = m_list.front()->getSeqnum();
 }
 
 void ReliablePacketBuffer::incrementTimeouts(float dtime)
 {
        MutexAutoLock listlock(m_list_mutex);
-       for (BufferedPacket &bufferedPacket : m_list) {
-               bufferedPacket.time += dtime;
-               bufferedPacket.totaltime += dtime;
+       for (auto &packet : m_list) {
+               packet->time += dtime;
+               packet->totaltime += dtime;
        }
 }
 
-std::list<BufferedPacket>
+std::list<ConstSharedPtr<BufferedPacket>>
        ReliablePacketBuffer::getTimedOuts(float timeout, u32 max_packets)
 {
        MutexAutoLock listlock(m_list_mutex);
-       std::list<BufferedPacket> timed_outs;
-       for (BufferedPacket &bufferedPacket : m_list) {
-               if (bufferedPacket.time >= timeout) {
-                       // caller will resend packet so reset time and increase counter
-                       bufferedPacket.time = 0.0f;
-                       bufferedPacket.resend_count++;
+       std::list<ConstSharedPtr<BufferedPacket>> timed_outs;
+       for (auto &packet : m_list) {
+               if (packet->time < timeout)
+                       continue;
 
-                       timed_outs.push_back(bufferedPacket);
+               // caller will resend packet so reset time and increase counter
+               packet->time = 0.0f;
+               packet->resend_count++;
 
-                       if (timed_outs.size() >= max_packets)
-                               break;
-               }
+               timed_outs.emplace_back(packet);
+
+               if (timed_outs.size() >= max_packets)
+                       break;
        }
        return timed_outs;
 }
@@ -428,11 +423,13 @@ IncomingSplitBuffer::~IncomingSplitBuffer()
        }
 }
 
-SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool reliable)
+SharedBuffer<u8> IncomingSplitBuffer::insert(BufferedPacketPtr &p_ptr, bool reliable)
 {
        MutexAutoLock listlock(m_map_mutex);
+       const BufferedPacket &p = *p_ptr;
+
        u32 headersize = BASE_HEADER_SIZE + 7;
-       if (p.data.getSize() < headersize) {
+       if (p.size() < headersize) {
                errorstream << "Invalid data size for split packet" << std::endl;
                return SharedBuffer<u8>();
        }
@@ -473,7 +470,7 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool relia
                                <<std::endl);
 
        // Cut chunk data out of packet
-       u32 chunkdatasize = p.data.getSize() - headersize;
+       u32 chunkdatasize = p.size() - headersize;
        SharedBuffer<u8> chunkdata(chunkdatasize);
        memcpy(*chunkdata, &(p.data[headersize]), chunkdatasize);
 
@@ -520,14 +517,67 @@ void IncomingSplitBuffer::removeUnreliableTimedOuts(float dtime, float timeout)
        ConnectionCommand
  */
 
-void ConnectionCommand::send(session_t peer_id_, u8 channelnum_, NetworkPacket *pkt,
-       bool reliable_)
+ConnectionCommandPtr ConnectionCommand::create(ConnectionCommandType type)
+{
+       return ConnectionCommandPtr(new ConnectionCommand(type));
+}
+
+ConnectionCommandPtr ConnectionCommand::serve(Address address)
 {
-       type = CONNCMD_SEND;
-       peer_id = peer_id_;
-       channelnum = channelnum_;
-       data = pkt->oldForgePacket();
-       reliable = reliable_;
+       auto c = create(CONNCMD_SERVE);
+       c->address = address;
+       return c;
+}
+
+ConnectionCommandPtr ConnectionCommand::connect(Address address)
+{
+       auto c = create(CONNCMD_CONNECT);
+       c->address = address;
+       return c;
+}
+
+ConnectionCommandPtr ConnectionCommand::disconnect()
+{
+       return create(CONNCMD_DISCONNECT);
+}
+
+ConnectionCommandPtr ConnectionCommand::disconnect_peer(session_t peer_id)
+{
+       auto c = create(CONNCMD_DISCONNECT_PEER);
+       c->peer_id = peer_id;
+       return c;
+}
+
+ConnectionCommandPtr ConnectionCommand::send(session_t peer_id, u8 channelnum,
+       NetworkPacket *pkt, bool reliable)
+{
+       auto c = create(CONNCMD_SEND);
+       c->peer_id = peer_id;
+       c->channelnum = channelnum;
+       c->reliable = reliable;
+       c->data = pkt->oldForgePacket();
+       return c;
+}
+
+ConnectionCommandPtr ConnectionCommand::ack(session_t peer_id, u8 channelnum, const Buffer<u8> &data)
+{
+       auto c = create(CONCMD_ACK);
+       c->peer_id = peer_id;
+       c->channelnum = channelnum;
+       c->reliable = false;
+       data.copyTo(c->data);
+       return c;
+}
+
+ConnectionCommandPtr ConnectionCommand::createPeer(session_t peer_id, const Buffer<u8> &data)
+{
+       auto c = create(CONCMD_CREATE_PEER);
+       c->peer_id = peer_id;
+       c->channelnum = 0;
+       c->reliable = true;
+       c->raw = true;
+       data.copyTo(c->data);
+       return c;
 }
 
 /*
@@ -562,39 +612,38 @@ void Channel::setNextSplitSeqNum(u16 seqnum)
 u16 Channel::getOutgoingSequenceNumber(bool& successful)
 {
        MutexAutoLock internal(m_internal_mutex);
+
        u16 retval = next_outgoing_seqnum;
-       u16 lowest_unacked_seqnumber;
+       successful = false;
 
        /* shortcut if there ain't any packet in outgoing list */
-       if (outgoing_reliables_sent.empty())
-       {
+       if (outgoing_reliables_sent.empty()) {
+               successful = true;
                next_outgoing_seqnum++;
                return retval;
        }
 
-       if (outgoing_reliables_sent.getFirstSeqnum(lowest_unacked_seqnumber))
-       {
+       u16 lowest_unacked_seqnumber;
+       if (outgoing_reliables_sent.getFirstSeqnum(lowest_unacked_seqnumber)) {
                if (lowest_unacked_seqnumber < next_outgoing_seqnum) {
                        // ugly cast but this one is required in order to tell compiler we
                        // know about difference of two unsigned may be negative in general
                        // but we already made sure it won't happen in this case
-                       if (((u16)(next_outgoing_seqnum - lowest_unacked_seqnumber)) > window_size) {
-                               successful = false;
+                       if (((u16)(next_outgoing_seqnum - lowest_unacked_seqnumber)) > m_window_size) {
                                return 0;
                        }
-               }
-               else {
+               } else {
                        // ugly cast but this one is required in order to tell compiler we
                        // know about difference of two unsigned may be negative in general
                        // but we already made sure it won't happen in this case
                        if ((next_outgoing_seqnum + (u16)(SEQNUM_MAX - lowest_unacked_seqnumber)) >
-                               window_size) {
-                               successful = false;
+                                       m_window_size) {
                                return 0;
                        }
                }
        }
 
+       successful = true;
        next_outgoing_seqnum++;
        return retval;
 }
@@ -666,7 +715,7 @@ void Channel::UpdateTimers(float dtime)
                        //packet_too_late = current_packet_too_late;
                        packets_successful = current_packet_successful;
 
-                       if (current_bytes_transfered > (unsigned int) (window_size*512/2)) {
+                       if (current_bytes_transfered > (unsigned int) (m_window_size*512/2)) {
                                reasonable_amount_of_data_transmitted = true;
                        }
                        current_packet_loss = 0;
@@ -681,37 +730,25 @@ void Channel::UpdateTimers(float dtime)
                if (packets_successful > 0) {
                        successful_to_lost_ratio = packet_loss/packets_successful;
                } else if (packet_loss > 0) {
-                       window_size = std::max(
-                                       (window_size - 10),
-                                       MIN_RELIABLE_WINDOW_SIZE);
+                       setWindowSize(m_window_size - 10);
                        done = true;
                }
 
                if (!done) {
-                       if ((successful_to_lost_ratio < 0.01f) &&
-                               (window_size < MAX_RELIABLE_WINDOW_SIZE)) {
+                       if (successful_to_lost_ratio < 0.01f) {
                                /* don't even think about increasing if we didn't even
                                 * use major parts of our window */
                                if (reasonable_amount_of_data_transmitted)
-                                       window_size = std::min(
-                                                       (window_size + 100),
-                                                       MAX_RELIABLE_WINDOW_SIZE);
-                       } else if ((successful_to_lost_ratio < 0.05f) &&
-                                       (window_size < MAX_RELIABLE_WINDOW_SIZE)) {
+                                       setWindowSize(m_window_size + 100);
+                       } else if (successful_to_lost_ratio < 0.05f) {
                                /* don't even think about increasing if we didn't even
                                 * use major parts of our window */
                                if (reasonable_amount_of_data_transmitted)
-                                       window_size = std::min(
-                                                       (window_size + 50),
-                                                       MAX_RELIABLE_WINDOW_SIZE);
+                                       setWindowSize(m_window_size + 50);
                        } else if (successful_to_lost_ratio > 0.15f) {
-                               window_size = std::max(
-                                               (window_size - 100),
-                                               MIN_RELIABLE_WINDOW_SIZE);
+                               setWindowSize(m_window_size - 100);
                        } else if (successful_to_lost_ratio > 0.1f) {
-                               window_size = std::max(
-                                               (window_size - 50),
-                                               MIN_RELIABLE_WINDOW_SIZE);
+                               setWindowSize(m_window_size - 50);
                        }
                }
        }
@@ -958,45 +995,45 @@ bool UDPPeer::Ping(float dtime,SharedBuffer<u8>& data)
        return false;
 }
 
-void UDPPeer::PutReliableSendCommand(ConnectionCommand &c,
+void UDPPeer::PutReliableSendCommand(ConnectionCommandPtr &c,
                unsigned int max_packet_size)
 {
        if (m_pending_disconnect)
                return;
 
-       Channel &chan = channels[c.channelnum];
+       Channel &chan = channels[c->channelnum];
 
        if (chan.queued_commands.empty() &&
                        /* don't queue more packets then window size */
-                       (chan.queued_reliables.size() < chan.getWindowSize() / 2)) {
+                       (chan.queued_reliables.size() + 1 < chan.getWindowSize() / 2)) {
                LOG(dout_con<<m_connection->getDesc()
-                               <<" processing reliable command for peer id: " << c.peer_id
-                               <<" data size: " << c.data.getSize() << std::endl);
-               if (!processReliableSendCommand(c,max_packet_size)) {
-                       chan.queued_commands.push_back(c);
-               }
-       }
-       else {
+                               <<" processing reliable command for peer id: " << c->peer_id
+                               <<" data size: " << c->data.getSize() << std::endl);
+               if (processReliableSendCommand(c, max_packet_size))
+                       return;
+       } else {
                LOG(dout_con<<m_connection->getDesc()
-                               <<" Queueing reliable command for peer id: " << c.peer_id
-                               <<" data size: " << c.data.getSize() <<std::endl);
-               chan.queued_commands.push_back(c);
-               if (chan.queued_commands.size() >= chan.getWindowSize() / 2) {
+                               <<" Queueing reliable command for peer id: " << c->peer_id
+                               <<" data size: " << c->data.getSize() <<std::endl);
+
+               if (chan.queued_commands.size() + 1 >= chan.getWindowSize() / 2) {
                        LOG(derr_con << m_connection->getDesc()
-                                       << "Possible packet stall to peer id: " << c.peer_id
+                                       << "Possible packet stall to peer id: " << c->peer_id
                                        << " queued_commands=" << chan.queued_commands.size()
                                        << std::endl);
                }
        }
+       chan.queued_commands.push_back(c);
 }
 
 bool UDPPeer::processReliableSendCommand(
-                               ConnectionCommand &c,
+                               ConnectionCommandPtr &c_ptr,
                                unsigned int max_packet_size)
 {
        if (m_pending_disconnect)
                return true;
 
+       const auto &c = *c_ptr;
        Channel &chan = channels[c.channelnum];
 
        u32 chunksize_max = max_packet_size
@@ -1015,9 +1052,9 @@ bool UDPPeer::processReliableSendCommand(
                chan.setNextSplitSeqNum(split_sequence_number);
        }
 
-       bool have_sequence_number = true;
+       bool have_sequence_number = false;
        bool have_initial_sequence_number = false;
-       std::queue<BufferedPacket> toadd;
+       std::queue<BufferedPacketPtr> toadd;
        volatile u16 initial_sequence_number = 0;
 
        for (SharedBuffer<u8> &original : originals) {
@@ -1036,25 +1073,23 @@ bool UDPPeer::processReliableSendCommand(
                SharedBuffer<u8> reliable = makeReliablePacket(original, seqnum);
 
                // Add base headers and make a packet
-               BufferedPacket p = con::makePacket(address, reliable,
+               BufferedPacketPtr p = con::makePacket(address, reliable,
                                m_connection->GetProtocolID(), m_connection->GetPeerID(),
                                c.channelnum);
 
-               toadd.push(std::move(p));
+               toadd.push(p);
        }
 
        if (have_sequence_number) {
-               volatile u16 pcount = 0;
                while (!toadd.empty()) {
-                       BufferedPacket p = std::move(toadd.front());
+                       BufferedPacketPtr p = toadd.front();
                        toadd.pop();
 //                     LOG(dout_con<<connection->getDesc()
 //                                     << " queuing reliable packet for peer_id: " << c.peer_id
 //                                     << " channel: " << (c.channelnum&0xFF)
 //                                     << " seqnum: " << readU16(&p.data[BASE_HEADER_SIZE+1])
 //                                     << std::endl)
-                       chan.queued_reliables.push(std::move(p));
-                       pcount++;
+                       chan.queued_reliables.push(p);
                }
                sanity_check(chan.queued_reliables.size() < 0xFFFF);
                return true;
@@ -1063,6 +1098,7 @@ bool UDPPeer::processReliableSendCommand(
        volatile u16 packets_available = toadd.size();
        /* we didn't get a single sequence number no need to fill queue */
        if (!have_initial_sequence_number) {
+               LOG(derr_con << m_connection->getDesc() << "Ran out of sequence numbers!" << std::endl);
                return false;
        }
 
@@ -1108,18 +1144,18 @@ void UDPPeer::RunCommandQueues(
                                (channel.queued_reliables.size() < maxtransfer) &&
                                (commands_processed < maxcommands)) {
                        try {
-                               ConnectionCommand c = channel.queued_commands.front();
+                               ConnectionCommandPtr c = channel.queued_commands.front();
 
                                LOG(dout_con << m_connection->getDesc()
                                                << " processing queued reliable command " << std::endl);
 
                                // Packet is processed, remove it from queue
-                               if (processReliableSendCommand(c,max_packet_size)) {
+                               if (processReliableSendCommand(c, max_packet_size)) {
                                        channel.queued_commands.pop_front();
                                } else {
                                        LOG(dout_con << m_connection->getDesc()
-                                                       << " Failed to queue packets for peer_id: " << c.peer_id
-                                                       << ", delaying sending of " << c.data.getSize()
+                                                       << " Failed to queue packets for peer_id: " << c->peer_id
+                                                       << ", delaying sending of " << c->data.getSize()
                                                        << " bytes" << std::endl);
                                }
                        }
@@ -1142,13 +1178,70 @@ void UDPPeer::setNextSplitSequenceNumber(u8 channel, u16 seqnum)
        channels[channel].setNextSplitSeqNum(seqnum);
 }
 
-SharedBuffer<u8> UDPPeer::addSplitPacket(u8 channel, const BufferedPacket &toadd,
+SharedBuffer<u8> UDPPeer::addSplitPacket(u8 channel, BufferedPacketPtr &toadd,
        bool reliable)
 {
        assert(channel < CHANNEL_COUNT); // Pre-condition
        return channels[channel].incoming_splits.insert(toadd, reliable);
 }
 
+/*
+       ConnectionEvent
+*/
+
+const char *ConnectionEvent::describe() const
+{
+       switch(type) {
+       case CONNEVENT_NONE:
+               return "CONNEVENT_NONE";
+       case CONNEVENT_DATA_RECEIVED:
+               return "CONNEVENT_DATA_RECEIVED";
+       case CONNEVENT_PEER_ADDED:
+               return "CONNEVENT_PEER_ADDED";
+       case CONNEVENT_PEER_REMOVED:
+               return "CONNEVENT_PEER_REMOVED";
+       case CONNEVENT_BIND_FAILED:
+               return "CONNEVENT_BIND_FAILED";
+       }
+       return "Invalid ConnectionEvent";
+}
+
+
+ConnectionEventPtr ConnectionEvent::create(ConnectionEventType type)
+{
+       return std::shared_ptr<ConnectionEvent>(new ConnectionEvent(type));
+}
+
+ConnectionEventPtr ConnectionEvent::dataReceived(session_t peer_id, const Buffer<u8> &data)
+{
+       auto e = create(CONNEVENT_DATA_RECEIVED);
+       e->peer_id = peer_id;
+       data.copyTo(e->data);
+       return e;
+}
+
+ConnectionEventPtr ConnectionEvent::peerAdded(session_t peer_id, Address address)
+{
+       auto e = create(CONNEVENT_PEER_ADDED);
+       e->peer_id = peer_id;
+       e->address = address;
+       return e;
+}
+
+ConnectionEventPtr ConnectionEvent::peerRemoved(session_t peer_id, bool is_timeout, Address address)
+{
+       auto e = create(CONNEVENT_PEER_REMOVED);
+       e->peer_id = peer_id;
+       e->timeout = is_timeout;
+       e->address = address;
+       return e;
+}
+
+ConnectionEventPtr ConnectionEvent::bindFailed()
+{
+       return create(CONNEVENT_BIND_FAILED);
+}
+
 /*
        Connection
 */
@@ -1198,18 +1291,12 @@ Connection::~Connection()
 
 /* Internal stuff */
 
-void Connection::putEvent(const ConnectionEvent &e)
+void Connection::putEvent(ConnectionEventPtr e)
 {
-       assert(e.type != CONNEVENT_NONE); // Pre-condition
+       assert(e->type != CONNEVENT_NONE); // Pre-condition
        m_event_queue.push_back(e);
 }
 
-void Connection::putEvent(ConnectionEvent &&e)
-{
-       assert(e.type != CONNEVENT_NONE); // Pre-condition
-       m_event_queue.push_back(std::move(e));
-}
-
 void Connection::TriggerSend()
 {
        m_sendThread->Trigger();
@@ -1272,11 +1359,9 @@ bool Connection::deletePeer(session_t peer_id, bool timeout)
        Address peer_address;
        //any peer has a primary address this never fails!
        peer->getAddress(MTP_PRIMARY, peer_address);
-       // Create event
-       ConnectionEvent e;
-       e.peerRemoved(peer_id, timeout, peer_address);
-       putEvent(e);
 
+       // Create event
+       putEvent(ConnectionEvent::peerRemoved(peer_id, timeout, peer_address));
 
        peer->Drop();
        return true;
@@ -1284,18 +1369,16 @@ bool Connection::deletePeer(session_t peer_id, bool timeout)
 
 /* Interface */
 
-ConnectionEvent Connection::waitEvent(u32 timeout_ms)
+ConnectionEventPtr Connection::waitEvent(u32 timeout_ms)
 {
        try {
                return m_event_queue.pop_front(timeout_ms);
        } catch(ItemNotFoundException &ex) {
-               ConnectionEvent e;
-               e.type = CONNEVENT_NONE;
-               return e;
+               return ConnectionEvent::create(CONNEVENT_NONE);
        }
 }
 
-void Connection::putCommand(const ConnectionCommand &c)
+void Connection::putCommand(ConnectionCommandPtr c)
 {
        if (!m_shutting_down) {
                m_command_queue.push_back(c);
@@ -1303,26 +1386,14 @@ void Connection::putCommand(const ConnectionCommand &c)
        }
 }
 
-void Connection::putCommand(ConnectionCommand &&c)
-{
-       if (!m_shutting_down) {
-               m_command_queue.push_back(std::move(c));
-               m_sendThread->Trigger();
-       }
-}
-
 void Connection::Serve(Address bind_addr)
 {
-       ConnectionCommand c;
-       c.serve(bind_addr);
-       putCommand(c);
+       putCommand(ConnectionCommand::serve(bind_addr));
 }
 
 void Connection::Connect(Address address)
 {
-       ConnectionCommand c;
-       c.connect(address);
-       putCommand(c);
+       putCommand(ConnectionCommand::connect(address));
 }
 
 bool Connection::Connected()
@@ -1344,9 +1415,7 @@ bool Connection::Connected()
 
 void Connection::Disconnect()
 {
-       ConnectionCommand c;
-       c.disconnect();
-       putCommand(c);
+       putCommand(ConnectionCommand::disconnect());
 }
 
 bool Connection::Receive(NetworkPacket *pkt, u32 timeout)
@@ -1357,11 +1426,15 @@ bool Connection::Receive(NetworkPacket *pkt, u32 timeout)
                This is not considered to be a problem (is it?)
        */
        for(;;) {
-               ConnectionEvent e = waitEvent(timeout);
-               if (e.type != CONNEVENT_NONE)
+               ConnectionEventPtr e_ptr = waitEvent(timeout);
+               const ConnectionEvent &e = *e_ptr;
+
+               if (e.type != CONNEVENT_NONE) {
                        LOG(dout_con << getDesc() << ": Receive: got event: "
                                        << e.describe() << std::endl);
-               switch(e.type) {
+               }
+
+               switch (e.type) {
                case CONNEVENT_NONE:
                        return false;
                case CONNEVENT_DATA_RECEIVED:
@@ -1409,10 +1482,7 @@ void Connection::Send(session_t peer_id, u8 channelnum,
 {
        assert(channelnum < CHANNEL_COUNT); // Pre-condition
 
-       ConnectionCommand c;
-
-       c.send(peer_id, channelnum, pkt, reliable);
-       putCommand(std::move(c));
+       putCommand(ConnectionCommand::send(peer_id, channelnum, pkt, reliable));
 }
 
 Address Connection::GetPeerAddress(session_t peer_id)
@@ -1511,41 +1581,31 @@ u16 Connection::createPeer(Address& sender, MTProtocols protocol, int fd)
        LOG(dout_con << getDesc()
                        << "createPeer(): giving peer_id=" << peer_id_new << std::endl);
 
-       ConnectionCommand cmd;
-       Buffer<u8> reply(4);
-       writeU8(&reply[0], PACKET_TYPE_CONTROL);
-       writeU8(&reply[1], CONTROLTYPE_SET_PEER_ID);
-       writeU16(&reply[2], peer_id_new);
-       cmd.createPeer(peer_id_new,reply);
-       putCommand(std::move(cmd));
+       {
+               Buffer<u8> reply(4);
+               writeU8(&reply[0], PACKET_TYPE_CONTROL);
+               writeU8(&reply[1], CONTROLTYPE_SET_PEER_ID);
+               writeU16(&reply[2], peer_id_new);
+               putCommand(ConnectionCommand::createPeer(peer_id_new, reply));
+       }
 
        // Create peer addition event
-       ConnectionEvent e;
-       e.peerAdded(peer_id_new, sender);
-       putEvent(e);
+       putEvent(ConnectionEvent::peerAdded(peer_id_new, sender));
 
        // We're now talking to a valid peer_id
        return peer_id_new;
 }
 
-void Connection::PrintInfo(std::ostream &out)
-{
-       m_info_mutex.lock();
-       out<<getDesc()<<": ";
-       m_info_mutex.unlock();
-}
-
 const std::string Connection::getDesc()
 {
+       MutexAutoLock _(m_info_mutex);
        return std::string("con(")+
                        itos(m_udpSocket.GetHandle())+"/"+itos(m_peer_id)+")";
 }
 
 void Connection::DisconnectPeer(session_t peer_id)
 {
-       ConnectionCommand discon;
-       discon.disconnect_peer(peer_id);
-       putCommand(discon);
+       putCommand(ConnectionCommand::disconnect_peer(peer_id));
 }
 
 void Connection::sendAck(session_t peer_id, u8 channelnum, u16 seqnum)
@@ -1557,14 +1617,12 @@ void Connection::sendAck(session_t peer_id, u8 channelnum, u16 seqnum)
                        " channel: " << (channelnum & 0xFF) <<
                        " seqnum: " << seqnum << std::endl);
 
-       ConnectionCommand c;
        SharedBuffer<u8> ack(4);
        writeU8(&ack[0], PACKET_TYPE_CONTROL);
        writeU8(&ack[1], CONTROLTYPE_ACK);
        writeU16(&ack[2], seqnum);
 
-       c.ack(peer_id, channelnum, ack);
-       putCommand(std::move(c));
+       putCommand(ConnectionCommand::ack(peer_id, channelnum, ack));
        m_sendThread->Trigger();
 }
 
index 49bb65c3edc7ba9b9756cc01e98ff0babdbfedc0..b5ae24882abbd093821f86aa6d39d429348986be 100644 (file)
@@ -32,6 +32,95 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <vector>
 #include <map>
 
+#define MAX_UDP_PEERS 65535
+
+/*
+=== NOTES ===
+
+A packet is sent through a channel to a peer with a basic header:
+       Header (7 bytes):
+       [0] u32 protocol_id
+       [4] session_t sender_peer_id
+       [6] u8 channel
+sender_peer_id:
+       Unique to each peer.
+       value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
+       value 1 (PEER_ID_SERVER) is reserved for server
+       these constants are defined in constants.h
+channel:
+       Channel numbers have no intrinsic meaning. Currently only 0, 1, 2 exist.
+*/
+#define BASE_HEADER_SIZE 7
+#define CHANNEL_COUNT 3
+
+/*
+Packet types:
+
+CONTROL: This is a packet used by the protocol.
+- When this is processed, nothing is handed to the user.
+       Header (2 byte):
+       [0] u8 type
+       [1] u8 controltype
+controltype and data description:
+       CONTROLTYPE_ACK
+               [2] u16 seqnum
+       CONTROLTYPE_SET_PEER_ID
+               [2] session_t peer_id_new
+       CONTROLTYPE_PING
+       - There is no actual reply, but this can be sent in a reliable
+         packet to get a reply
+       CONTROLTYPE_DISCO
+*/
+enum ControlType : u8 {
+       CONTROLTYPE_ACK = 0,
+       CONTROLTYPE_SET_PEER_ID = 1,
+       CONTROLTYPE_PING = 2,
+       CONTROLTYPE_DISCO = 3,
+};
+
+/*
+ORIGINAL: This is a plain packet with no control and no error
+checking at all.
+- When this is processed, it is directly handed to the user.
+       Header (1 byte):
+       [0] u8 type
+*/
+//#define TYPE_ORIGINAL 1
+#define ORIGINAL_HEADER_SIZE 1
+
+/*
+SPLIT: These are sequences of packets forming one bigger piece of
+data.
+- When processed and all the packet_nums 0...packet_count-1 are
+  present (this should be buffered), the resulting data shall be
+  directly handed to the user.
+- If the data fails to come up in a reasonable time, the buffer shall
+  be silently discarded.
+- These can be sent as-is or atop of a RELIABLE packet stream.
+       Header (7 bytes):
+       [0] u8 type
+       [1] u16 seqnum
+       [3] u16 chunk_count
+       [5] u16 chunk_num
+*/
+//#define TYPE_SPLIT 2
+
+/*
+RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
+and they shall be delivered in the same order as sent. This is done
+with a buffer in the receiving and transmitting end.
+- When this is processed, the contents of each packet is recursively
+  processed as packets.
+       Header (3 bytes):
+       [0] u8 type
+       [1] u16 seqnum
+
+*/
+//#define TYPE_RELIABLE 3
+#define RELIABLE_HEADER_SIZE 3
+#define SEQNUM_INITIAL 65500
+#define SEQNUM_MAX 65535
+
 class NetworkPacket;
 
 namespace con
@@ -46,9 +135,13 @@ typedef enum MTProtocols {
        MTP_MINETEST_RELIABLE_UDP
 } MTProtocols;
 
-#define MAX_UDP_PEERS 65535
-
-#define SEQNUM_MAX 65535
+enum PacketType : u8 {
+       PACKET_TYPE_CONTROL = 0,
+       PACKET_TYPE_ORIGINAL = 1,
+       PACKET_TYPE_SPLIT = 2,
+       PACKET_TYPE_RELIABLE = 3,
+       PACKET_TYPE_MAX
+};
 
 inline bool seqnum_higher(u16 totest, u16 base)
 {
@@ -85,24 +178,40 @@ static inline float CALC_DTIME(u64 lasttime, u64 curtime)
        return MYMAX(MYMIN(value,0.1),0.0);
 }
 
-struct BufferedPacket
-{
-       BufferedPacket(u8 *a_data, u32 a_size):
-               data(a_data, a_size)
-       {}
-       BufferedPacket(u32 a_size):
-               data(a_size)
-       {}
-       Buffer<u8> data; // Data of the packet, including headers
+/*
+       Struct for all kinds of packets. Includes following data:
+               BASE_HEADER
+               u8[] packet data (usually copied from SharedBuffer<u8>)
+*/
+struct BufferedPacket {
+       BufferedPacket(u32 a_size)
+       {
+               m_data.resize(a_size);
+               data = &m_data[0];
+       }
+
+       DISABLE_CLASS_COPY(BufferedPacket)
+
+       u16 getSeqnum() const;
+
+       inline size_t size() const { return m_data.size(); }
+
+       u8 *data; // Direct memory access
        float time = 0.0f; // Seconds from buffering the packet or re-sending
        float totaltime = 0.0f; // Seconds from buffering the packet
        u64 absolute_send_time = -1;
        Address address; // Sender or destination
        unsigned int resend_count = 0;
+
+private:
+       std::vector<u8> m_data; // Data of the packet, including headers
 };
 
+typedef std::shared_ptr<BufferedPacket> BufferedPacketPtr;
+
+
 // This adds the base headers to the data and makes a packet out of it
-BufferedPacket makePacket(Address &address, const SharedBuffer<u8> &data,
+BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data,
                u32 protocol_id, session_t sender_peer_id, u8 channel);
 
 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
@@ -136,101 +245,12 @@ struct IncomingSplitPacket
        std::map<u16, SharedBuffer<u8>> chunks;
 };
 
-/*
-=== NOTES ===
-
-A packet is sent through a channel to a peer with a basic header:
-       Header (7 bytes):
-       [0] u32 protocol_id
-       [4] session_t sender_peer_id
-       [6] u8 channel
-sender_peer_id:
-       Unique to each peer.
-       value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
-       value 1 (PEER_ID_SERVER) is reserved for server
-       these constants are defined in constants.h
-channel:
-       Channel numbers have no intrinsic meaning. Currently only 0, 1, 2 exist.
-*/
-#define BASE_HEADER_SIZE 7
-#define CHANNEL_COUNT 3
-/*
-Packet types:
-
-CONTROL: This is a packet used by the protocol.
-- When this is processed, nothing is handed to the user.
-       Header (2 byte):
-       [0] u8 type
-       [1] u8 controltype
-controltype and data description:
-       CONTROLTYPE_ACK
-               [2] u16 seqnum
-       CONTROLTYPE_SET_PEER_ID
-               [2] session_t peer_id_new
-       CONTROLTYPE_PING
-       - There is no actual reply, but this can be sent in a reliable
-         packet to get a reply
-       CONTROLTYPE_DISCO
-*/
-//#define TYPE_CONTROL 0
-#define CONTROLTYPE_ACK 0
-#define CONTROLTYPE_SET_PEER_ID 1
-#define CONTROLTYPE_PING 2
-#define CONTROLTYPE_DISCO 3
-
-/*
-ORIGINAL: This is a plain packet with no control and no error
-checking at all.
-- When this is processed, it is directly handed to the user.
-       Header (1 byte):
-       [0] u8 type
-*/
-//#define TYPE_ORIGINAL 1
-#define ORIGINAL_HEADER_SIZE 1
-/*
-SPLIT: These are sequences of packets forming one bigger piece of
-data.
-- When processed and all the packet_nums 0...packet_count-1 are
-  present (this should be buffered), the resulting data shall be
-  directly handed to the user.
-- If the data fails to come up in a reasonable time, the buffer shall
-  be silently discarded.
-- These can be sent as-is or atop of a RELIABLE packet stream.
-       Header (7 bytes):
-       [0] u8 type
-       [1] u16 seqnum
-       [3] u16 chunk_count
-       [5] u16 chunk_num
-*/
-//#define TYPE_SPLIT 2
-/*
-RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
-and they shall be delivered in the same order as sent. This is done
-with a buffer in the receiving and transmitting end.
-- When this is processed, the contents of each packet is recursively
-  processed as packets.
-       Header (3 bytes):
-       [0] u8 type
-       [1] u16 seqnum
-
-*/
-//#define TYPE_RELIABLE 3
-#define RELIABLE_HEADER_SIZE 3
-#define SEQNUM_INITIAL 65500
-
-enum PacketType: u8 {
-       PACKET_TYPE_CONTROL = 0,
-       PACKET_TYPE_ORIGINAL = 1,
-       PACKET_TYPE_SPLIT = 2,
-       PACKET_TYPE_RELIABLE = 3,
-       PACKET_TYPE_MAX
-};
 /*
        A buffer which stores reliable packets and sorts them internally
        for fast access to the smallest one.
 */
 
-typedef std::list<BufferedPacket>::iterator RPBSearchResult;
+typedef std::list<BufferedPacketPtr>::iterator RPBSearchResult;
 
 class ReliablePacketBuffer
 {
@@ -239,12 +259,12 @@ class ReliablePacketBuffer
 
        bool getFirstSeqnum(u16& result);
 
-       BufferedPacket popFirst();
-       BufferedPacket popSeqnum(u16 seqnum);
-       void insert(const BufferedPacket &p, u16 next_expected);
+       BufferedPacketPtr popFirst();
+       BufferedPacketPtr popSeqnum(u16 seqnum);
+       void insert(BufferedPacketPtr &p_ptr, u16 next_expected);
 
        void incrementTimeouts(float dtime);
-       std::list<BufferedPacket> getTimedOuts(float timeout, u32 max_packets);
+       std::list<ConstSharedPtr<BufferedPacket>> getTimedOuts(float timeout, u32 max_packets);
 
        void print();
        bool empty();
@@ -252,10 +272,9 @@ class ReliablePacketBuffer
 
 
 private:
-       RPBSearchResult findPacket(u16 seqnum); // does not perform locking
-       inline RPBSearchResult notFound() { return m_list.end(); }
+       RPBSearchResult findPacketNoLock(u16 seqnum);
 
-       std::list<BufferedPacket> m_list;
+       std::list<BufferedPacketPtr> m_list;
 
        u16 m_oldest_non_answered_ack;
 
@@ -274,7 +293,7 @@ class IncomingSplitBuffer
                Returns a reference counted buffer of length != 0 when a full split
                packet is constructed. If not, returns one of length 0.
        */
-       SharedBuffer<u8> insert(const BufferedPacket &p, bool reliable);
+       SharedBuffer<u8> insert(BufferedPacketPtr &p_ptr, bool reliable);
 
        void removeUnreliableTimedOuts(float dtime, float timeout);
 
@@ -285,25 +304,6 @@ class IncomingSplitBuffer
        std::mutex m_map_mutex;
 };
 
-struct OutgoingPacket
-{
-       session_t peer_id;
-       u8 channelnum;
-       SharedBuffer<u8> data;
-       bool reliable;
-       bool ack;
-
-       OutgoingPacket(session_t peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
-                       bool reliable_,bool ack_=false):
-               peer_id(peer_id_),
-               channelnum(channelnum_),
-               data(data_),
-               reliable(reliable_),
-               ack(ack_)
-       {
-       }
-};
-
 enum ConnectionCommandType{
        CONNCMD_NONE,
        CONNCMD_SERVE,
@@ -316,9 +316,13 @@ enum ConnectionCommandType{
        CONCMD_CREATE_PEER
 };
 
+struct ConnectionCommand;
+typedef std::shared_ptr<ConnectionCommand> ConnectionCommandPtr;
+
+// This is very similar to ConnectionEvent
 struct ConnectionCommand
 {
-       enum ConnectionCommandType type = CONNCMD_NONE;
+       const ConnectionCommandType type;
        Address address;
        session_t peer_id = PEER_ID_INEXISTENT;
        u8 channelnum = 0;
@@ -326,48 +330,21 @@ struct ConnectionCommand
        bool reliable = false;
        bool raw = false;
 
-       ConnectionCommand() = default;
+       DISABLE_CLASS_COPY(ConnectionCommand);
 
-       void serve(Address address_)
-       {
-               type = CONNCMD_SERVE;
-               address = address_;
-       }
-       void connect(Address address_)
-       {
-               type = CONNCMD_CONNECT;
-               address = address_;
-       }
-       void disconnect()
-       {
-               type = CONNCMD_DISCONNECT;
-       }
-       void disconnect_peer(session_t peer_id_)
-       {
-               type = CONNCMD_DISCONNECT_PEER;
-               peer_id = peer_id_;
-       }
+       static ConnectionCommandPtr serve(Address address);
+       static ConnectionCommandPtr connect(Address address);
+       static ConnectionCommandPtr disconnect();
+       static ConnectionCommandPtr disconnect_peer(session_t peer_id);
+       static ConnectionCommandPtr send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable);
+       static ConnectionCommandPtr ack(session_t peer_id, u8 channelnum, const Buffer<u8> &data);
+       static ConnectionCommandPtr createPeer(session_t peer_id, const Buffer<u8> &data);
 
-       void send(session_t peer_id_, u8 channelnum_, NetworkPacket *pkt, bool reliable_);
-
-       void ack(session_t peer_id_, u8 channelnum_, const Buffer<u8> &data_)
-       {
-               type = CONCMD_ACK;
-               peer_id = peer_id_;
-               channelnum = channelnum_;
-               data = data_;
-               reliable = false;
-       }
+private:
+       ConnectionCommand(ConnectionCommandType type_) :
+               type(type_) {}
 
-       void createPeer(session_t peer_id_, const Buffer<u8> &data_)
-       {
-               type = CONCMD_CREATE_PEER;
-               peer_id = peer_id_;
-               data = data_;
-               channelnum = 0;
-               reliable = true;
-               raw = true;
-       }
+       static ConnectionCommandPtr create(ConnectionCommandType type);
 };
 
 /* maximum window size to use, 0xFFFF is theoretical maximum. don't think about
@@ -402,10 +379,10 @@ class Channel
        ReliablePacketBuffer outgoing_reliables_sent;
 
        //queued reliable packets
-       std::queue<BufferedPacket> queued_reliables;
+       std::queue<BufferedPacketPtr> queued_reliables;
 
        //queue commands prior splitting to packets
-       std::deque<ConnectionCommand> queued_commands;
+       std::deque<ConnectionCommandPtr> queued_commands;
 
        IncomingSplitBuffer incoming_splits;
 
@@ -420,34 +397,38 @@ class Channel
 
        void UpdateTimers(float dtime);
 
-       const float getCurrentDownloadRateKB()
+       float getCurrentDownloadRateKB()
                { MutexAutoLock lock(m_internal_mutex); return cur_kbps; };
-       const float getMaxDownloadRateKB()
+       float getMaxDownloadRateKB()
                { MutexAutoLock lock(m_internal_mutex); return max_kbps; };
 
-       const float getCurrentLossRateKB()
+       float getCurrentLossRateKB()
                { MutexAutoLock lock(m_internal_mutex); return cur_kbps_lost; };
-       const float getMaxLossRateKB()
+       float getMaxLossRateKB()
                { MutexAutoLock lock(m_internal_mutex); return max_kbps_lost; };
 
-       const float getCurrentIncomingRateKB()
+       float getCurrentIncomingRateKB()
                { MutexAutoLock lock(m_internal_mutex); return cur_incoming_kbps; };
-       const float getMaxIncomingRateKB()
+       float getMaxIncomingRateKB()
                { MutexAutoLock lock(m_internal_mutex); return max_incoming_kbps; };
 
-       const float getAvgDownloadRateKB()
+       float getAvgDownloadRateKB()
                { MutexAutoLock lock(m_internal_mutex); return avg_kbps; };
-       const float getAvgLossRateKB()
+       float getAvgLossRateKB()
                { MutexAutoLock lock(m_internal_mutex); return avg_kbps_lost; };
-       const float getAvgIncomingRateKB()
+       float getAvgIncomingRateKB()
                { MutexAutoLock lock(m_internal_mutex); return avg_incoming_kbps; };
 
-       const unsigned int getWindowSize() const { return window_size; };
+       u16 getWindowSize() const { return m_window_size; };
+
+       void setWindowSize(long size)
+       {
+               m_window_size = (u16)rangelim(size, MIN_RELIABLE_WINDOW_SIZE, MAX_RELIABLE_WINDOW_SIZE);
+       }
 
-       void setWindowSize(unsigned int size) { window_size = size; };
 private:
        std::mutex m_internal_mutex;
-       int window_size = MIN_RELIABLE_WINDOW_SIZE;
+       u16 m_window_size = MIN_RELIABLE_WINDOW_SIZE;
 
        u16 next_incoming_seqnum = SEQNUM_INITIAL;
 
@@ -510,7 +491,7 @@ class Peer {
        public:
                friend class PeerHelper;
 
-               Peer(Address address_,u16 id_,Connection* connection) :
+               Peer(Address address_,session_t id_,Connection* connection) :
                        id(id_),
                        m_connection(connection),
                        address(address_),
@@ -524,11 +505,11 @@ class Peer {
                };
 
                // Unique id of the peer
-               u16 id;
+               const session_t id;
 
                void Drop();
 
-               virtual void PutReliableSendCommand(ConnectionCommand &c,
+               virtual void PutReliableSendCommand(ConnectionCommandPtr &c,
                                                unsigned int max_packet_size) {};
 
                virtual bool getAddress(MTProtocols type, Address& toset) = 0;
@@ -545,7 +526,7 @@ class Peer {
 
                virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
                virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
-               virtual SharedBuffer<u8> addSplitPacket(u8 channel, const BufferedPacket &toadd,
+               virtual SharedBuffer<u8> addSplitPacket(u8 channel, BufferedPacketPtr &toadd,
                                bool reliable)
                {
                        errorstream << "Peer::addSplitPacket called,"
@@ -582,7 +563,7 @@ class Peer {
                bool IncUseCount();
                void DecUseCount();
 
-               std::mutex m_exclusive_access_mutex;
+               mutable std::mutex m_exclusive_access_mutex;
 
                bool m_pending_deletion = false;
 
@@ -630,7 +611,7 @@ class UDPPeer : public Peer
        UDPPeer(u16 a_id, Address a_address, Connection* connection);
        virtual ~UDPPeer() = default;
 
-       void PutReliableSendCommand(ConnectionCommand &c,
+       void PutReliableSendCommand(ConnectionCommandPtr &c,
                                                        unsigned int max_packet_size);
 
        bool getAddress(MTProtocols type, Address& toset);
@@ -638,7 +619,7 @@ class UDPPeer : public Peer
        u16 getNextSplitSequenceNumber(u8 channel);
        void setNextSplitSequenceNumber(u8 channel, u16 seqnum);
 
-       SharedBuffer<u8> addSplitPacket(u8 channel, const BufferedPacket &toadd,
+       SharedBuffer<u8> addSplitPacket(u8 channel, BufferedPacketPtr &toadd,
                bool reliable);
 
 protected:
@@ -667,7 +648,7 @@ class UDPPeer : public Peer
        float resend_timeout = 0.5;
 
        bool processReliableSendCommand(
-                                       ConnectionCommand &c,
+                                       ConnectionCommandPtr &c_ptr,
                                        unsigned int max_packet_size);
 };
 
@@ -675,7 +656,7 @@ class UDPPeer : public Peer
        Connection
 */
 
-enum ConnectionEventType{
+enum ConnectionEventType {
        CONNEVENT_NONE,
        CONNEVENT_DATA_RECEIVED,
        CONNEVENT_PEER_ADDED,
@@ -683,56 +664,32 @@ enum ConnectionEventType{
        CONNEVENT_BIND_FAILED,
 };
 
+struct ConnectionEvent;
+typedef std::shared_ptr<ConnectionEvent> ConnectionEventPtr;
+
+// This is very similar to ConnectionCommand
 struct ConnectionEvent
 {
-       enum ConnectionEventType type = CONNEVENT_NONE;
+       const ConnectionEventType type;
        session_t peer_id = 0;
        Buffer<u8> data;
        bool timeout = false;
        Address address;
 
-       ConnectionEvent() = default;
+       // We don't want to copy "data"
+       DISABLE_CLASS_COPY(ConnectionEvent);
 
-       const char *describe() const
-       {
-               switch(type) {
-               case CONNEVENT_NONE:
-                       return "CONNEVENT_NONE";
-               case CONNEVENT_DATA_RECEIVED:
-                       return "CONNEVENT_DATA_RECEIVED";
-               case CONNEVENT_PEER_ADDED:
-                       return "CONNEVENT_PEER_ADDED";
-               case CONNEVENT_PEER_REMOVED:
-                       return "CONNEVENT_PEER_REMOVED";
-               case CONNEVENT_BIND_FAILED:
-                       return "CONNEVENT_BIND_FAILED";
-               }
-               return "Invalid ConnectionEvent";
-       }
+       static ConnectionEventPtr create(ConnectionEventType type);
+       static ConnectionEventPtr dataReceived(session_t peer_id, const Buffer<u8> &data);
+       static ConnectionEventPtr peerAdded(session_t peer_id, Address address);
+       static ConnectionEventPtr peerRemoved(session_t peer_id, bool is_timeout, Address address);
+       static ConnectionEventPtr bindFailed();
 
-       void dataReceived(session_t peer_id_, const Buffer<u8> &data_)
-       {
-               type = CONNEVENT_DATA_RECEIVED;
-               peer_id = peer_id_;
-               data = data_;
-       }
-       void peerAdded(session_t peer_id_, Address address_)
-       {
-               type = CONNEVENT_PEER_ADDED;
-               peer_id = peer_id_;
-               address = address_;
-       }
-       void peerRemoved(session_t peer_id_, bool timeout_, Address address_)
-       {
-               type = CONNEVENT_PEER_REMOVED;
-               peer_id = peer_id_;
-               timeout = timeout_;
-               address = address_;
-       }
-       void bindFailed()
-       {
-               type = CONNEVENT_BIND_FAILED;
-       }
+       const char *describe() const;
+
+private:
+       ConnectionEvent(ConnectionEventType type_) :
+               type(type_) {}
 };
 
 class PeerHandler;
@@ -748,10 +705,9 @@ class Connection
        ~Connection();
 
        /* Interface */
-       ConnectionEvent waitEvent(u32 timeout_ms);
-       // Warning: creates an unnecessary copy, prefer putCommand(T&&) if possible
-       void putCommand(const ConnectionCommand &c);
-       void putCommand(ConnectionCommand &&c);
+       ConnectionEventPtr waitEvent(u32 timeout_ms);
+
+       void putCommand(ConnectionCommandPtr c);
 
        void SetTimeoutMs(u32 timeout) { m_bc_receive_timeout = timeout; }
        void Serve(Address bind_addr);
@@ -765,7 +721,7 @@ class Connection
        Address GetPeerAddress(session_t peer_id);
        float getPeerStat(session_t peer_id, rtt_stat_type type);
        float getLocalStat(rate_stat_type type);
-       const u32 GetProtocolID() const { return m_protocol_id; };
+       u32 GetProtocolID() const { return m_protocol_id; };
        const std::string getDesc();
        void DisconnectPeer(session_t peer_id);
 
@@ -781,8 +737,6 @@ class Connection
 
        void sendAck(session_t peer_id, u8 channelnum, u16 seqnum);
 
-       void PrintInfo(std::ostream &out);
-
        std::vector<session_t> getPeerIDs()
        {
                MutexAutoLock peerlock(m_peers_mutex);
@@ -791,23 +745,21 @@ class Connection
 
        UDPSocket m_udpSocket;
        // Command queue: user -> SendThread
-       MutexedQueue<ConnectionCommand> m_command_queue;
+       MutexedQueue<ConnectionCommandPtr> m_command_queue;
 
        bool Receive(NetworkPacket *pkt, u32 timeout);
 
-       // Warning: creates an unnecessary copy, prefer putEvent(T&&) if possible
-       void putEvent(const ConnectionEvent &e);
-       void putEvent(ConnectionEvent &&e);
+       void putEvent(ConnectionEventPtr e);
 
        void TriggerSend();
-       
-       bool ConnectedToServer() 
+
+       bool ConnectedToServer()
        {
                return getPeerNoEx(PEER_ID_SERVER) != nullptr;
        }
 private:
        // Event queue: ReceiveThread -> user
-       MutexedQueue<ConnectionEvent> m_event_queue;
+       MutexedQueue<ConnectionEventPtr> m_event_queue;
 
        session_t m_peer_id = 0;
        u32 m_protocol_id;
@@ -819,7 +771,7 @@ class Connection
        std::unique_ptr<ConnectionSendThread> m_sendThread;
        std::unique_ptr<ConnectionReceiveThread> m_receiveThread;
 
-       std::mutex m_info_mutex;
+       mutable std::mutex m_info_mutex;
 
        // Backwards compatibility
        PeerHandler *m_bc_peerhandler;
index 47678dac58378c178f703285015dca9b73670085..90936b43dc90ae744c94120cdb730259890c0002 100644 (file)
@@ -32,32 +32,25 @@ namespace con
 /* defines used for debugging and profiling                                   */
 /******************************************************************************/
 #ifdef NDEBUG
-#define LOG(a) a
 #define PROFILE(a)
 #undef DEBUG_CONNECTION_KBPS
 #else
 /* this mutex is used to achieve log message consistency */
-std::mutex log_conthread_mutex;
-#define LOG(a)                                                                \
-       {                                                                         \
-       MutexAutoLock loglock(log_conthread_mutex);                                 \
-       a;                                                                        \
-       }
 #define PROFILE(a) a
 //#define DEBUG_CONNECTION_KBPS
 #undef DEBUG_CONNECTION_KBPS
 #endif
 
-/* maximum number of retries for reliable packets */
-#define MAX_RELIABLE_RETRY 5
+// TODO: Clean this up.
+#define LOG(a) a
 
 #define WINDOW_SIZE 5
 
-static session_t readPeerId(u8 *packetdata)
+static session_t readPeerId(const u8 *packetdata)
 {
        return readU16(&packetdata[4]);
 }
-static u8 readChannel(u8 *packetdata)
+static u8 readChannel(const u8 *packetdata)
 {
        return readU8(&packetdata[6]);
 }
@@ -117,9 +110,9 @@ void *ConnectionSendThread::run()
                }
 
                /* translate commands to packets */
-               ConnectionCommand c = m_connection->m_command_queue.pop_frontNoEx(0);
-               while (c.type != CONNCMD_NONE) {
-                       if (c.reliable)
+               auto c = m_connection->m_command_queue.pop_frontNoEx(0);
+               while (c && c->type != CONNCMD_NONE) {
+                       if (c->reliable)
                                processReliableCommand(c);
                        else
                                processNonReliableCommand(c);
@@ -212,7 +205,6 @@ void ConnectionSendThread::runTimeouts(float dtime)
                }
 
                float resend_timeout = udpPeer->getResendTimeout();
-               bool retry_count_exceeded = false;
                for (Channel &channel : udpPeer->channels) {
 
                        // Remove timed out incomplete unreliable split packets
@@ -231,45 +223,29 @@ void ConnectionSendThread::runTimeouts(float dtime)
                        m_iteration_packets_avaialble -= timed_outs.size();
 
                        for (const auto &k : timed_outs) {
-                               session_t peer_id = readPeerId(*k.data);
-                               u8 channelnum = readChannel(*k.data);
-                               u16 seqnum = readU16(&(k.data[BASE_HEADER_SIZE + 1]));
+                               u8 channelnum = readChannel(k->data);
+                               u16 seqnum = k->getSeqnum();
 
-                               channel.UpdateBytesLost(k.data.getSize());
-
-                               if (k.resend_count > MAX_RELIABLE_RETRY) {
-                                       retry_count_exceeded = true;
-                                       timeouted_peers.push_back(peer->id);
-                                       /* no need to check additional packets if a single one did timeout*/
-                                       break;
-                               }
+                               channel.UpdateBytesLost(k->size());
 
                                LOG(derr_con << m_connection->getDesc()
                                        << "RE-SENDING timed-out RELIABLE to "
-                                       << k.address.serializeString()
+                                       << k->address.serializeString()
                                        << "(t/o=" << resend_timeout << "): "
-                                       << "from_peer_id=" << peer_id
+                                       << "count=" << k->resend_count
                                        << ", channel=" << ((int) channelnum & 0xff)
                                        << ", seqnum=" << seqnum
                                        << std::endl);
 
-                               rawSend(k);
+                               rawSend(k.get());
 
                                // do not handle rtt here as we can't decide if this packet was
                                // lost or really takes more time to transmit
                        }
 
-                       if (retry_count_exceeded) {
-                               break; /* no need to check other channels if we already did timeout */
-                       }
-
                        channel.UpdateTimers(dtime);
                }
 
-               /* skip to next peer if we did timeout */
-               if (retry_count_exceeded)
-                       continue;
-
                /* send ping if necessary */
                if (udpPeer->Ping(dtime, data)) {
                        LOG(dout_con << m_connection->getDesc()
@@ -294,25 +270,24 @@ void ConnectionSendThread::runTimeouts(float dtime)
        }
 }
 
-void ConnectionSendThread::rawSend(const BufferedPacket &packet)
+void ConnectionSendThread::rawSend(const BufferedPacket *p)
 {
        try {
-               m_connection->m_udpSocket.Send(packet.address, *packet.data,
-                       packet.data.getSize());
+               m_connection->m_udpSocket.Send(p->address, p->data, p->size());
                LOG(dout_con << m_connection->getDesc()
-                       << " rawSend: " << packet.data.getSize()
+                       << " rawSend: " << p->size()
                        << " bytes sent" << std::endl);
        } catch (SendFailedException &e) {
                LOG(derr_con << m_connection->getDesc()
                        << "Connection::rawSend(): SendFailedException: "
-                       << packet.address.serializeString() << std::endl);
+                       << p->address.serializeString() << std::endl);
        }
 }
 
-void ConnectionSendThread::sendAsPacketReliable(BufferedPacket &p, Channel *channel)
+void ConnectionSendThread::sendAsPacketReliable(BufferedPacketPtr &p, Channel *channel)
 {
        try {
-               p.absolute_send_time = porting::getTimeMs();
+               p->absolute_send_time = porting::getTimeMs();
                // Buffer the packet
                channel->outgoing_reliables_sent.insert(p,
                        (channel->readOutgoingSequenceNumber() - MAX_RELIABLE_WINDOW_SIZE)
@@ -325,7 +300,7 @@ void ConnectionSendThread::sendAsPacketReliable(BufferedPacket &p, Channel *chan
        }
 
        // Send the packet
-       rawSend(p);
+       rawSend(p.get());
 }
 
 bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
@@ -341,11 +316,10 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
        Channel *channel = &(dynamic_cast<UDPPeer *>(&peer)->channels[channelnum]);
 
        if (reliable) {
-               bool have_sequence_number_for_raw_packet = true;
-               u16 seqnum =
-                       channel->getOutgoingSequenceNumber(have_sequence_number_for_raw_packet);
+               bool have_seqnum = false;
+               const u16 seqnum = channel->getOutgoingSequenceNumber(have_seqnum);
 
-               if (!have_sequence_number_for_raw_packet)
+               if (!have_seqnum)
                        return false;
 
                SharedBuffer<u8> reliable = makeReliablePacket(data, seqnum);
@@ -353,13 +327,12 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
                peer->getAddress(MTP_MINETEST_RELIABLE_UDP, peer_address);
 
                // Add base headers and make a packet
-               BufferedPacket p = con::makePacket(peer_address, reliable,
+               BufferedPacketPtr p = con::makePacket(peer_address, reliable,
                        m_connection->GetProtocolID(), m_connection->GetPeerID(),
                        channelnum);
 
                // first check if our send window is already maxed out
-               if (channel->outgoing_reliables_sent.size()
-                       < channel->getWindowSize()) {
+               if (channel->outgoing_reliables_sent.size() < channel->getWindowSize()) {
                        LOG(dout_con << m_connection->getDesc()
                                << " INFO: sending a reliable packet to peer_id " << peer_id
                                << " channel: " << (u32)channelnum
@@ -372,19 +345,19 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
                        << " INFO: queueing reliable packet for peer_id: " << peer_id
                        << " channel: " << (u32)channelnum
                        << " seqnum: " << seqnum << std::endl);
-               channel->queued_reliables.push(std::move(p));
+               channel->queued_reliables.push(p);
                return false;
        }
 
        Address peer_address;
        if (peer->getAddress(MTP_UDP, peer_address)) {
                // Add base headers and make a packet
-               BufferedPacket p = con::makePacket(peer_address, data,
+               BufferedPacketPtr p = con::makePacket(peer_address, data,
                        m_connection->GetProtocolID(), m_connection->GetPeerID(),
                        channelnum);
 
                // Send the packet
-               rawSend(p);
+               rawSend(p.get());
                return true;
        }
 
@@ -394,11 +367,11 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
        return false;
 }
 
-void ConnectionSendThread::processReliableCommand(ConnectionCommand &c)
+void ConnectionSendThread::processReliableCommand(ConnectionCommandPtr &c)
 {
-       assert(c.reliable);  // Pre-condition
+       assert(c->reliable);  // Pre-condition
 
-       switch (c.type) {
+       switch (c->type) {
                case CONNCMD_NONE:
                        LOG(dout_con << m_connection->getDesc()
                                << "UDP processing reliable CONNCMD_NONE" << std::endl);
@@ -419,7 +392,7 @@ void ConnectionSendThread::processReliableCommand(ConnectionCommand &c)
                case CONCMD_CREATE_PEER:
                        LOG(dout_con << m_connection->getDesc()
                                << "UDP processing reliable CONCMD_CREATE_PEER" << std::endl);
-                       if (!rawSendAsPacket(c.peer_id, c.channelnum, c.data, c.reliable)) {
+                       if (!rawSendAsPacket(c->peer_id, c->channelnum, c->data, c->reliable)) {
                                /* put to queue if we couldn't send it immediately */
                                sendReliable(c);
                        }
@@ -432,13 +405,14 @@ void ConnectionSendThread::processReliableCommand(ConnectionCommand &c)
                        FATAL_ERROR("Got command that shouldn't be reliable as reliable command");
                default:
                        LOG(dout_con << m_connection->getDesc()
-                               << " Invalid reliable command type: " << c.type << std::endl);
+                               << " Invalid reliable command type: " << c->type << std::endl);
        }
 }
 
 
-void ConnectionSendThread::processNonReliableCommand(ConnectionCommand &c)
+void ConnectionSendThread::processNonReliableCommand(ConnectionCommandPtr &c_ptr)
 {
+       const ConnectionCommand &c = *c_ptr;
        assert(!c.reliable); // Pre-condition
 
        switch (c.type) {
@@ -500,9 +474,7 @@ void ConnectionSendThread::serve(Address bind_address)
        }
        catch (SocketException &e) {
                // Create event
-               ConnectionEvent ce;
-               ce.bindFailed();
-               m_connection->putEvent(ce);
+               m_connection->putEvent(ConnectionEvent::bindFailed());
        }
 }
 
@@ -515,9 +487,7 @@ void ConnectionSendThread::connect(Address address)
        UDPPeer *peer = m_connection->createServerPeer(address);
 
        // Create event
-       ConnectionEvent e;
-       e.peerAdded(peer->id, peer->address);
-       m_connection->putEvent(e);
+       m_connection->putEvent(ConnectionEvent::peerAdded(peer->id, peer->address));
 
        Address bind_addr;
 
@@ -606,9 +576,9 @@ void ConnectionSendThread::send(session_t peer_id, u8 channelnum,
        }
 }
 
-void ConnectionSendThread::sendReliable(ConnectionCommand &c)
+void ConnectionSendThread::sendReliable(ConnectionCommandPtr &c)
 {
-       PeerHelper peer = m_connection->getPeerNoEx(c.peer_id);
+       PeerHelper peer = m_connection->getPeerNoEx(c->peer_id);
        if (!peer)
                return;
 
@@ -624,7 +594,7 @@ void ConnectionSendThread::sendToAll(u8 channelnum, const SharedBuffer<u8> &data
        }
 }
 
-void ConnectionSendThread::sendToAllReliable(ConnectionCommand &c)
+void ConnectionSendThread::sendToAllReliable(ConnectionCommandPtr &c)
 {
        std::vector<session_t> peerids = m_connection->getPeerIDs();
 
@@ -683,8 +653,12 @@ void ConnectionSendThread::sendPackets(float dtime)
                // first send queued reliable packets for all peers (if possible)
                for (unsigned int i = 0; i < CHANNEL_COUNT; i++) {
                        Channel &channel = udpPeer->channels[i];
-                       u16 next_to_ack = 0;
 
+                       // Reduces logging verbosity
+                       if (channel.queued_reliables.empty())
+                               continue;
+
+                       u16 next_to_ack = 0;
                        channel.outgoing_reliables_sent.getFirstSeqnum(next_to_ack);
                        u16 next_to_receive = 0;
                        channel.incoming_reliables.getFirstSeqnum(next_to_receive);
@@ -714,13 +688,13 @@ void ConnectionSendThread::sendPackets(float dtime)
                                        channel.outgoing_reliables_sent.size()
                                        < channel.getWindowSize() &&
                                        peer->m_increment_packets_remaining > 0) {
-                               BufferedPacket p = std::move(channel.queued_reliables.front());
+                               BufferedPacketPtr p = channel.queued_reliables.front();
                                channel.queued_reliables.pop();
 
                                LOG(dout_con << m_connection->getDesc()
                                        << " INFO: sending a queued reliable packet "
                                        << " channel: " << i
-                                       << ", seqnum: " << readU16(&p.data[BASE_HEADER_SIZE + 1])
+                                       << ", seqnum: " << p->getSeqnum()
                                        << std::endl);
 
                                sendAsPacketReliable(p, &channel);
@@ -901,17 +875,14 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata,
        try {
                // First, see if there any buffered packets we can process now
                if (packet_queued) {
-                       bool data_left = true;
                        session_t peer_id;
                        SharedBuffer<u8> resultdata;
-                       while (data_left) {
+                       while (true) {
                                try {
-                                       data_left = getFromBuffers(peer_id, resultdata);
-                                       if (data_left) {
-                                               ConnectionEvent e;
-                                               e.dataReceived(peer_id, resultdata);
-                                               m_connection->putEvent(std::move(e));
-                                       }
+                                       if (!getFromBuffers(peer_id, resultdata))
+                                               break;
+
+                                       m_connection->putEvent(ConnectionEvent::dataReceived(peer_id, resultdata));
                                }
                                catch (ProcessedSilentlyException &e) {
                                        /* try reading again */
@@ -928,7 +899,7 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata,
                        return;
 
                if ((received_size < BASE_HEADER_SIZE) ||
-                       (readU32(&packetdata[0]) != m_connection->GetProtocolID())) {
+                               (readU32(&packetdata[0]) != m_connection->GetProtocolID())) {
                        LOG(derr_con << m_connection->getDesc()
                                << "Receive(): Invalid incoming packet, "
                                << "size: " << received_size
@@ -1019,9 +990,7 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata,
                                << ", channel: " << (u32)channelnum << ", returned "
                                << resultdata.getSize() << " bytes" << std::endl);
 
-                       ConnectionEvent e;
-                       e.dataReceived(peer_id, resultdata);
-                       m_connection->putEvent(std::move(e));
+                       m_connection->putEvent(ConnectionEvent::dataReceived(peer_id, resultdata));
                }
                catch (ProcessedSilentlyException &e) {
                }
@@ -1046,10 +1015,11 @@ bool ConnectionReceiveThread::getFromBuffers(session_t &peer_id, SharedBuffer<u8
                if (!peer)
                        continue;
 
-               if (dynamic_cast<UDPPeer *>(&peer) == 0)
+               UDPPeer *p = dynamic_cast<UDPPeer *>(&peer);
+               if (!p)
                        continue;
 
-               for (Channel &channel : (dynamic_cast<UDPPeer *>(&peer))->channels) {
+               for (Channel &channel : p->channels) {
                        if (checkIncomingBuffers(&channel, peer_id, dst)) {
                                return true;
                        }
@@ -1062,32 +1032,34 @@ bool ConnectionReceiveThread::checkIncomingBuffers(Channel *channel,
        session_t &peer_id, SharedBuffer<u8> &dst)
 {
        u16 firstseqnum = 0;
-       if (channel->incoming_reliables.getFirstSeqnum(firstseqnum)) {
-               if (firstseqnum == channel->readNextIncomingSeqNum()) {
-                       BufferedPacket p = channel->incoming_reliables.popFirst();
-                       peer_id = readPeerId(*p.data);
-                       u8 channelnum = readChannel(*p.data);
-                       u16 seqnum = readU16(&p.data[BASE_HEADER_SIZE + 1]);
+       if (!channel->incoming_reliables.getFirstSeqnum(firstseqnum))
+               return false;
 
-                       LOG(dout_con << m_connection->getDesc()
-                               << "UNBUFFERING TYPE_RELIABLE"
-                               << " seqnum=" << seqnum
-                               << " peer_id=" << peer_id
-                               << " channel=" << ((int) channelnum & 0xff)
-                               << std::endl);
+       if (firstseqnum != channel->readNextIncomingSeqNum())
+               return false;
 
-                       channel->incNextIncomingSeqNum();
+       BufferedPacketPtr p = channel->incoming_reliables.popFirst();
 
-                       u32 headers_size = BASE_HEADER_SIZE + RELIABLE_HEADER_SIZE;
-                       // Get out the inside packet and re-process it
-                       SharedBuffer<u8> payload(p.data.getSize() - headers_size);
-                       memcpy(*payload, &p.data[headers_size], payload.getSize());
+       peer_id = readPeerId(p->data); // Carried over to caller function
+       u8 channelnum = readChannel(p->data);
+       u16 seqnum = p->getSeqnum();
 
-                       dst = processPacket(channel, payload, peer_id, channelnum, true);
-                       return true;
-               }
-       }
-       return false;
+       LOG(dout_con << m_connection->getDesc()
+               << "UNBUFFERING TYPE_RELIABLE"
+               << " seqnum=" << seqnum
+               << " peer_id=" << peer_id
+               << " channel=" << ((int) channelnum & 0xff)
+               << std::endl);
+
+       channel->incNextIncomingSeqNum();
+
+       u32 headers_size = BASE_HEADER_SIZE + RELIABLE_HEADER_SIZE;
+       // Get out the inside packet and re-process it
+       SharedBuffer<u8> payload(p->size() - headers_size);
+       memcpy(*payload, &p->data[headers_size], payload.getSize());
+
+       dst = processPacket(channel, payload, peer_id, channelnum, true);
+       return true;
 }
 
 SharedBuffer<u8> ConnectionReceiveThread::processPacket(Channel *channel,
@@ -1135,7 +1107,7 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Control(Channel *chan
        if (packetdata.getSize() < 2)
                throw InvalidIncomingDataException("packetdata.getSize() < 2");
 
-       u8 controltype = readU8(&(packetdata[1]));
+       ControlType controltype = (ControlType)readU8(&(packetdata[1]));
 
        if (controltype == CONTROLTYPE_ACK) {
                assert(channel != NULL);
@@ -1151,31 +1123,32 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Control(Channel *chan
                        << seqnum << " ]" << std::endl);
 
                try {
-                       BufferedPacket p = channel->outgoing_reliables_sent.popSeqnum(seqnum);
+                       BufferedPacketPtr p = channel->outgoing_reliables_sent.popSeqnum(seqnum);
 
-                       // only calculate rtt from straight sent packets
-                       if (p.resend_count == 0) {
+                       // the rtt calculation will be a bit off for re-sent packets but that's okay
+                       {
                                // Get round trip time
                                u64 current_time = porting::getTimeMs();
 
                                // a overflow is quite unlikely but as it'd result in major
                                // rtt miscalculation we handle it here
-                               if (current_time > p.absolute_send_time) {
-                                       float rtt = (current_time - p.absolute_send_time) / 1000.0;
+                               if (current_time > p->absolute_send_time) {
+                                       float rtt = (current_time - p->absolute_send_time) / 1000.0;
 
                                        // Let peer calculate stuff according to it
                                        // (avg_rtt and resend_timeout)
                                        dynamic_cast<UDPPeer *>(peer)->reportRTT(rtt);
-                               } else if (p.totaltime > 0) {
-                                       float rtt = p.totaltime;
+                               } else if (p->totaltime > 0) {
+                                       float rtt = p->totaltime;
 
                                        // Let peer calculate stuff according to it
                                        // (avg_rtt and resend_timeout)
                                        dynamic_cast<UDPPeer *>(peer)->reportRTT(rtt);
                                }
                        }
+
                        // put bytes for max bandwidth calculation
-                       channel->UpdateBytesSent(p.data.getSize(), 1);
+                       channel->UpdateBytesSent(p->size(), 1);
                        if (channel->outgoing_reliables_sent.size() == 0)
                                m_connection->TriggerSend();
                } catch (NotFoundException &e) {
@@ -1223,7 +1196,7 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Control(Channel *chan
                throw ProcessedSilentlyException("Got a DISCO");
        } else {
                LOG(derr_con << m_connection->getDesc()
-                       << "INVALID TYPE_CONTROL: invalid controltype="
+                       << "INVALID controltype="
                        << ((int) controltype & 0xff) << std::endl);
                throw InvalidIncomingDataException("Invalid control type");
        }
@@ -1251,7 +1224,7 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Split(Channel *channe
        if (peer->getAddress(MTP_UDP, peer_address)) {
                // We have to create a packet again for buffering
                // This isn't actually too bad an idea.
-               BufferedPacket packet = makePacket(peer_address,
+               BufferedPacketPtr packet = con::makePacket(peer_address,
                        packetdata,
                        m_connection->GetProtocolID(),
                        peer->id,
@@ -1286,7 +1259,7 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *cha
        if (packetdata.getSize() < RELIABLE_HEADER_SIZE)
                throw InvalidIncomingDataException("packetdata.getSize() < RELIABLE_HEADER_SIZE");
 
-       u16 seqnum = readU16(&packetdata[1]);
+       const u16 seqnum = readU16(&packetdata[1]);
        bool is_future_packet = false;
        bool is_old_packet = false;
 
@@ -1330,7 +1303,7 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *cha
                // This one comes later, buffer it.
                // Actually we have to make a packet to buffer one.
                // Well, we have all the ingredients, so just do it.
-               BufferedPacket packet = con::makePacket(
+               BufferedPacketPtr packet = con::makePacket(
                        peer_address,
                        packetdata,
                        m_connection->GetProtocolID(),
@@ -1347,9 +1320,7 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *cha
                        throw ProcessedQueued("Buffered future reliable packet");
                } catch (AlreadyExistsException &e) {
                } catch (IncomingDataCorruption &e) {
-                       ConnectionCommand discon;
-                       discon.disconnect_peer(peer->id);
-                       m_connection->putCommand(discon);
+                       m_connection->putCommand(ConnectionCommand::disconnect_peer(peer->id));
 
                        LOG(derr_con << m_connection->getDesc()
                                << "INVALID, TYPE_RELIABLE peer_id: " << peer->id
@@ -1370,7 +1341,7 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *cha
        u16 queued_seqnum = 0;
        if (channel->incoming_reliables.getFirstSeqnum(queued_seqnum)) {
                if (queued_seqnum == seqnum) {
-                       BufferedPacket queued_packet = channel->incoming_reliables.popFirst();
+                       BufferedPacketPtr queued_packet = channel->incoming_reliables.popFirst();
                        /** TODO find a way to verify the new against the old packet */
                }
        }
index 612407c3b5cf9190c6e665bbdb62736dc436ee99..c2e2dae123223c115b2cf022d875a506af99b6d3 100644 (file)
@@ -29,6 +29,25 @@ namespace con
 
 class Connection;
 
+struct OutgoingPacket
+{
+       session_t peer_id;
+       u8 channelnum;
+       SharedBuffer<u8> data;
+       bool reliable;
+       bool ack;
+
+       OutgoingPacket(session_t peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
+                       bool reliable_,bool ack_=false):
+               peer_id(peer_id_),
+               channelnum(channelnum_),
+               data(data_),
+               reliable(reliable_),
+               ack(ack_)
+       {
+       }
+};
+
 class ConnectionSendThread : public Thread
 {
 
@@ -51,27 +70,27 @@ class ConnectionSendThread : public Thread
 
 private:
        void runTimeouts(float dtime);
-       void rawSend(const BufferedPacket &packet);
+       void rawSend(const BufferedPacket *p);
        bool rawSendAsPacket(session_t peer_id, u8 channelnum,
                        const SharedBuffer<u8> &data, bool reliable);
 
-       void processReliableCommand(ConnectionCommand &c);
-       void processNonReliableCommand(ConnectionCommand &c);
+       void processReliableCommand(ConnectionCommandPtr &c);
+       void processNonReliableCommand(ConnectionCommandPtr &c);
        void serve(Address bind_address);
        void connect(Address address);
        void disconnect();
        void disconnect_peer(session_t peer_id);
        void send(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data);
-       void sendReliable(ConnectionCommand &c);
+       void sendReliable(ConnectionCommandPtr &c);
        void sendToAll(u8 channelnum, const SharedBuffer<u8> &data);
-       void sendToAllReliable(ConnectionCommand &c);
+       void sendToAllReliable(ConnectionCommandPtr &c);
 
        void sendPackets(float dtime);
 
        void sendAsPacket(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data,
                        bool ack = false);
 
-       void sendAsPacketReliable(BufferedPacket &p, Channel *channel);
+       void sendAsPacketReliable(BufferedPacketPtr &p, Channel *channel);
 
        bool packetsQueued();
 
index b1c44f055a6ad835348eb87496308b19f69f1304..b9c39f332a2f01d130aea1467a565caf11540300 100644 (file)
@@ -41,7 +41,7 @@ class NetworkPacket
        u32 getSize() const { return m_datasize; }
        session_t getPeerId() const { return m_peer_id; }
        u16 getCommand() { return m_command; }
-       const u32 getRemainingBytes() const { return m_datasize - m_read_offset; }
+       u32 getRemainingBytes() const { return m_datasize - m_read_offset; }
        const char *getRemainingString() { return getString(m_read_offset); }
 
        // Returns a c-string without copying.
index 8214cc5b1433157428b59dc8a5496c60b96002f9..3923cb85812e61dfc31d9a3e2ace8ff2522095c6 100644 (file)
@@ -206,7 +206,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
                Adds new sun, moon and stars packets
                Minimap modes
        PROTOCOL VERSION 40:
-               Added 'basic_debug' privilege
                TOCLIENT_MEDIA_PUSH changed, TOSERVER_HAVE_MEDIA added
 */
 
@@ -230,7 +229,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
                                // base64-encoded SHA-1 (27+\0).
 
 // See also: Formspec Version History in doc/lua_api.txt
-#define FORMSPEC_API_VERSION 4
+#define FORMSPEC_API_VERSION 5
 
 #define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-"
 
@@ -763,7 +762,12 @@ enum ToClientCommand
                        std::string extra
        */
 
-       TOCLIENT_NUM_MSG_TYPES = 0x63,
+       TOCLIENT_SET_LIGHTING = 0x63,
+       /*
+               f32 shadow_intensity
+       */
+
+       TOCLIENT_NUM_MSG_TYPES = 0x64,
 };
 
 enum ToServerCommand
@@ -1002,7 +1006,7 @@ enum AuthMechanism
        AUTH_MECHANISM_FIRST_SRP = 1 << 2,
 };
 
-enum AccessDeniedCode {
+enum AccessDeniedCode : u8 {
        SERVER_ACCESSDENIED_WRONG_PASSWORD,
        SERVER_ACCESSDENIED_UNEXPECTED_DATA,
        SERVER_ACCESSDENIED_SINGLEPLAYER,
@@ -1025,18 +1029,18 @@ enum NetProtoCompressionMode {
 
 const static std::string accessDeniedStrings[SERVER_ACCESSDENIED_MAX] = {
        "Invalid password",
-       "Your client sent something the server didn't expect.  Try reconnecting or updating your client",
+       "Your client sent something the server didn't expect.  Try reconnecting or updating your client.",
        "The server is running in simple singleplayer mode.  You cannot connect.",
-       "Your client's version is not supported.\nPlease contact server administrator.",
-       "Player name contains disallowed characters.",
-       "Player name not allowed.",
-       "Too many users.",
+       "Your client's version is not supported.\nPlease contact the server administrator.",
+       "Player name contains disallowed characters",
+       "Player name not allowed",
+       "Too many users",
        "Empty passwords are disallowed.  Set a password and try again.",
        "Another client is connected with this name.  If your client closed unexpectedly, try again in a minute.",
-       "Server authentication failed.  This is likely a server error.",
+       "Internal server error",
        "",
-       "Server shutting down.",
-       "This server has experienced an internal error. You will now be disconnected."
+       "Server shutting down",
+       "The server has experienced an internal error.  You will now be disconnected."
 };
 
 enum PlayerListModifer : u8
index 44b65e8daa2821933cbcefb28ce172dd152d10f0..12665e7f17fb0176e3095b5783a868657b0c83d5 100644 (file)
@@ -176,7 +176,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] =
        { "TOCLIENT_ACTIVE_OBJECT_MESSAGES",   0, true }, // 0x32 (may be sent as unrel over channel 1 too)
        { "TOCLIENT_HP",                       0, true }, // 0x33
        { "TOCLIENT_MOVE_PLAYER",              0, true }, // 0x34
-       { "TOCLIENT_ACCESS_DENIED_LEGACY",     0, true }, // 0x35
+       null_command_factory, // 0x35
        { "TOCLIENT_FOV",                      0, true }, // 0x36
        { "TOCLIENT_DEATHSCREEN",              0, true }, // 0x37
        { "TOCLIENT_MEDIA",                    2, true }, // 0x38
index 4c609644fa17c6cb6ceb6ef34904c2869f9ed85c..4b9de488c76b168cbb3e6f563177fe823c63e22d 100644 (file)
@@ -86,7 +86,7 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
 
        // Do not allow multiple players in simple singleplayer mode.
        // This isn't a perfect way to do it, but will suffice for now
-       if (m_simple_singleplayer_mode && m_clients.getClientIDs().size() > 1) {
+       if (m_simple_singleplayer_mode && !m_clients.getClientIDs().empty()) {
                infostream << "Server: Not allowing another client (" << addr_s <<
                        ") to connect in simple singleplayer mode" << std::endl;
                DenyAccess(peer_id, SERVER_ACCESSDENIED_SINGLEPLAYER);
@@ -227,7 +227,7 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
                Compose auth methods for answer
        */
        std::string encpwd; // encrypted Password field for the user
-       bool has_auth = m_script->getAuth(playername, &encpwd, NULL);
+       bool has_auth = m_script->getAuth(playername, &encpwd, nullptr);
        u32 auth_mechs = 0;
 
        client->chosen_mech = AUTH_MECHANISM_NONE;
@@ -380,55 +380,47 @@ void Server::handleCommand_ClientReady(NetworkPacket* pkt)
 {
        session_t peer_id = pkt->getPeerId();
 
-       PlayerSAO* playersao = StageTwoClientInit(peer_id);
-
-       if (playersao == NULL) {
-               errorstream << "TOSERVER_CLIENT_READY stage 2 client init failed "
-                       "peer_id=" << peer_id << std::endl;
-               DisconnectPeer(peer_id);
-               return;
-       }
-
-
-       if (pkt->getSize() < 8) {
-               errorstream << "TOSERVER_CLIENT_READY client sent inconsistent data, "
-                       "disconnecting peer_id: " << peer_id << std::endl;
-               DisconnectPeer(peer_id);
-               return;
-       }
-
+       // decode all information first
        u8 major_ver, minor_ver, patch_ver, reserved;
+       u16 formspec_ver = 1; // v1 for clients older than 5.1.0-dev
        std::string full_ver;
+
        *pkt >> major_ver >> minor_ver >> patch_ver >> reserved >> full_ver;
+       if (pkt->getRemainingBytes() >= 2)
+               *pkt >> formspec_ver;
 
        m_clients.setClientVersion(peer_id, major_ver, minor_ver, patch_ver,
                full_ver);
 
-       if (pkt->getRemainingBytes() >= 2)
-               *pkt >> playersao->getPlayer()->formspec_version;
-
-       const std::vector<std::string> &players = m_clients.getPlayerNames();
-       NetworkPacket list_pkt(TOCLIENT_UPDATE_PLAYER_LIST, 0, peer_id);
-       list_pkt << (u8) PLAYER_LIST_INIT << (u16) players.size();
-       for (const std::string &player: players) {
-               list_pkt <<  player;
+       // Emerge player
+       PlayerSAO* playersao = StageTwoClientInit(peer_id);
+       if (!playersao) {
+               errorstream << "Server: stage 2 client init failed "
+                       "peer_id=" << peer_id << std::endl;
+               DisconnectPeer(peer_id);
+               return;
        }
-       m_clients.send(peer_id, 0, &list_pkt, true);
 
-       NetworkPacket notice_pkt(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
-       // (u16) 1 + std::string represents a pseudo vector serialization representation
-       notice_pkt << (u8) PLAYER_LIST_ADD << (u16) 1 << std::string(playersao->getPlayer()->getName());
-       m_clients.sendToAll(&notice_pkt);
+       playersao->getPlayer()->formspec_version = formspec_ver;
        m_clients.event(peer_id, CSE_SetClientReady);
 
+       // Send player list to this client
+       {
+               const std::vector<std::string> &players = m_clients.getPlayerNames();
+               NetworkPacket list_pkt(TOCLIENT_UPDATE_PLAYER_LIST, 0, peer_id);
+               list_pkt << (u8) PLAYER_LIST_INIT << (u16) players.size();
+               for (const auto &player : players)
+                       list_pkt << player;
+               Send(peer_id, &list_pkt);
+       }
+
        s64 last_login;
        m_script->getAuth(playersao->getPlayer()->getName(), nullptr, nullptr, &last_login);
        m_script->on_joinplayer(playersao, last_login);
 
        // Send shutdown timer if shutdown has been scheduled
-       if (m_shutdown_state.isTimerRunning()) {
+       if (m_shutdown_state.isTimerRunning())
                SendChatMessage(peer_id, m_shutdown_state.getShutdownTimerMessage());
-       }
 }
 
 void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
@@ -452,7 +444,7 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
                                ("GOTBLOCKS length is too short");
        }
 
-       m_clients.lock();
+       ClientInterface::AutoLock lock(m_clients);
        RemoteClient *client = m_clients.lockedGetClientNoEx(pkt->getPeerId());
 
        for (u16 i = 0; i < count; i++) {
@@ -460,7 +452,6 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt)
                *pkt >> p;
                client->GotBlock(p);
        }
-       m_clients.unlock();
 }
 
 void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
@@ -482,7 +473,6 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
        f32 yaw = (f32)f32yaw / 100.0f;
        u32 keyPressed = 0;
 
-       // default behavior (in case an old client doesn't send these)
        f32 fov = 0;
        u8 wanted_range = 0;
 
@@ -508,13 +498,7 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
        playersao->setFov(fov);
        playersao->setWantedRange(wanted_range);
 
-       player->keyPressed = keyPressed;
-       player->control.jump  = (keyPressed & (0x1 << 4));
-       player->control.aux1  = (keyPressed & (0x1 << 5));
-       player->control.sneak = (keyPressed & (0x1 << 6));
-       player->control.dig   = (keyPressed & (0x1 << 7));
-       player->control.place = (keyPressed & (0x1 << 8));
-       player->control.zoom  = (keyPressed & (0x1 << 9));
+       player->control.unpackKeysPressed(keyPressed);
 
        if (playersao->checkMovementCheat()) {
                // Call callbacks
@@ -826,7 +810,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt)
                                << std::endl;
 
                PlayerHPChangeReason reason(PlayerHPChangeReason::FALL);
-               playersao->setHP((s32)playersao->getHP() - (s32)damage, reason);
+               playersao->setHP((s32)playersao->getHP() - (s32)damage, reason, true);
        }
 }
 
@@ -920,6 +904,13 @@ bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std:
        return true;
 }
 
+// Tiny helper to retrieve the selected item into an Optional
+static inline void getWieldedItem(const PlayerSAO *playersao, Optional<ItemStack> &ret)
+{
+       ret = ItemStack();
+       playersao->getWieldedItem(&(*ret));
+}
+
 void Server::handleCommand_Interact(NetworkPacket *pkt)
 {
        /*
@@ -1111,8 +1102,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
                float time_from_last_punch =
                        playersao->resetTimeFromLastPunch();
 
-               u16 wear = pointed_object->punch(dir, &toolcap, playersao,
-                               time_from_last_punch);
+               u32 wear = pointed_object->punch(dir, &toolcap, playersao,
+                               time_from_last_punch, tool_item.wear);
 
                // Callback may have changed item, so get it again
                playersao->getWieldedItem(&selected_item);
@@ -1165,7 +1156,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
 
                        // Get diggability and expected digging time
                        DigParams params = getDigParams(m_nodedef->get(n).groups,
-                                       &selected_item.getToolCapabilities(m_itemdef));
+                                       &selected_item.getToolCapabilities(m_itemdef),
+                                       selected_item.wear);
                        // If can't dig, try hand
                        if (!params.diggable) {
                                params = getDigParams(m_nodedef->get(n).groups,
@@ -1227,14 +1219,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
 
        // Place block or right-click object
        case INTERACT_PLACE: {
-               ItemStack selected_item;
-               playersao->getWieldedItem(&selected_item, nullptr);
+               Optional<ItemStack> selected_item;
+               getWieldedItem(playersao, selected_item);
 
                // Reset build time counter
                if (pointed.type == POINTEDTHING_NODE &&
-                               selected_item.getDefinition(m_itemdef).type == ITEM_NODE)
+                               selected_item->getDefinition(m_itemdef).type == ITEM_NODE)
                        getClient(peer_id)->m_time_from_building = 0.0;
 
+               const bool had_prediction = !selected_item->getDefinition(m_itemdef).
+                       node_placement_prediction.empty();
+
                if (pointed.type == POINTEDTHING_OBJECT) {
                        // Right click object
 
@@ -1247,11 +1242,9 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
                                        << pointed_object->getDescription() << std::endl;
 
                        // Do stuff
-                       if (m_script->item_OnSecondaryUse(
-                                       selected_item, playersao, pointed)) {
-                               if (playersao->setWieldedItem(selected_item)) {
+                       if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
+                               if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
                                        SendInventory(playersao, true);
-                               }
                        }
 
                        pointed_object->rightClick(playersao);
@@ -1259,7 +1252,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
                        // Placement was handled in lua
 
                        // Apply returned ItemStack
-                       if (playersao->setWieldedItem(selected_item))
+                       if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
                                SendInventory(playersao, true);
                }
 
@@ -1271,8 +1264,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
                RemoteClient *client = getClient(peer_id);
                v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface);
                v3s16 blockpos2 = getNodeBlockPos(pointed.node_undersurface);
-               if (!selected_item.getDefinition(m_itemdef
-                               ).node_placement_prediction.empty()) {
+               if (had_prediction) {
                        client->SetBlockNotSent(blockpos);
                        if (blockpos2 != blockpos)
                                client->SetBlockNotSent(blockpos2);
@@ -1286,15 +1278,15 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
        } // action == INTERACT_PLACE
 
        case INTERACT_USE: {
-               ItemStack selected_item;
-               playersao->getWieldedItem(&selected_item, nullptr);
+               Optional<ItemStack> selected_item;
+               getWieldedItem(playersao, selected_item);
 
-               actionstream << player->getName() << " uses " << selected_item.name
+               actionstream << player->getName() << " uses " << selected_item->name
                                << ", pointing at " << pointed.dump() << std::endl;
 
                if (m_script->item_OnUse(selected_item, playersao, pointed)) {
                        // Apply returned ItemStack
-                       if (playersao->setWieldedItem(selected_item))
+                       if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
                                SendInventory(playersao, true);
                }
 
@@ -1303,16 +1295,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
 
        // Rightclick air
        case INTERACT_ACTIVATE: {
-               ItemStack selected_item;
-               playersao->getWieldedItem(&selected_item, nullptr);
+               Optional<ItemStack> selected_item;
+               getWieldedItem(playersao, selected_item);
 
                actionstream << player->getName() << " activates "
-                               << selected_item.name << std::endl;
+                               << selected_item->name << std::endl;
 
                pointed.type = POINTEDTHING_NOTHING; // can only ever be NOTHING
 
                if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
-                       if (playersao->setWieldedItem(selected_item))
+                       // Apply returned ItemStack
+                       if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
                                SendInventory(playersao, true);
                }
 
@@ -1468,11 +1461,9 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt)
        session_t peer_id = pkt->getPeerId();
        RemoteClient *client = getClient(peer_id, CS_Invalid);
        ClientState cstate = client->getState();
+       const std::string playername = client->getName();
 
-       std::string playername = client->getName();
-
-       std::string salt;
-       std::string verification_key;
+       std::string salt, verification_key;
 
        std::string addr_s = getPeerAddress(peer_id).serializeString();
        u8 is_empty;
@@ -1482,6 +1473,9 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt)
        verbosestream << "Server: Got TOSERVER_FIRST_SRP from " << addr_s
                << ", with is_empty=" << (is_empty == 1) << std::endl;
 
+       const bool empty_disallowed = !isSingleplayer() && is_empty == 1 &&
+               g_settings->getBool("disallow_empty_password");
+
        // Either this packet is sent because the user is new or to change the password
        if (cstate == CS_HelloSent) {
                if (!client->isMechAllowed(AUTH_MECHANISM_FIRST_SRP)) {
@@ -1492,9 +1486,7 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt)
                        return;
                }
 
-               if (!isSingleplayer() &&
-                               g_settings->getBool("disallow_empty_password") &&
-                               is_empty == 1) {
+               if (empty_disallowed) {
                        actionstream << "Server: " << playername
                                        << " supplied empty password from " << addr_s << std::endl;
                        DenyAccess(peer_id, SERVER_ACCESSDENIED_EMPTY_PASSWORD);
@@ -1502,8 +1494,19 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt)
                }
 
                std::string initial_ver_key;
-
                initial_ver_key = encode_srp_verifier(verification_key, salt);
+
+               // It is possible for multiple connections to get this far with the same
+               // player name. In the end only one player with a given name will be emerged
+               // (see Server::StateTwoClientInit) but we still have to be careful here.
+               if (m_script->getAuth(playername, nullptr, nullptr)) {
+                       // Another client beat us to it
+                       actionstream << "Server: Client from " << addr_s
+                               << " tried to register " << playername << " a second time."
+                               << std::endl;
+                       DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED);
+                       return;
+               }
                m_script->createAuth(playername, initial_ver_key);
                m_script->on_authplayer(playername, addr_s, true);
 
@@ -1516,6 +1519,15 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt)
                        return;
                }
                m_clients.event(peer_id, CSE_SudoLeave);
+
+               if (empty_disallowed) {
+                       actionstream << "Server: " << playername
+                                       << " supplied empty password" << std::endl;
+                       SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
+                               L"Changing to an empty password is not allowed."));
+                       return;
+               }
+
                std::string pw_db_field = encode_srp_verifier(verification_key, salt);
                bool success = m_script->setPassword(playername, pw_db_field);
                if (success) {
@@ -1537,8 +1549,6 @@ void Server::handleCommand_SrpBytesA(NetworkPacket* pkt)
        RemoteClient *client = getClient(peer_id, CS_Invalid);
        ClientState cstate = client->getState();
 
-       bool wantSudo = (cstate == CS_Active);
-
        if (!((cstate == CS_HelloSent) || (cstate == CS_Active))) {
                actionstream << "Server: got SRP _A packet in wrong state " << cstate <<
                        " from " << getPeerAddress(peer_id).serializeString() <<
@@ -1546,6 +1556,8 @@ void Server::handleCommand_SrpBytesA(NetworkPacket* pkt)
                return;
        }
 
+       const bool wantSudo = (cstate == CS_Active);
+
        if (client->chosen_mech != AUTH_MECHANISM_NONE) {
                actionstream << "Server: got SRP _A packet, while auth is already "
                        "going on with mech " << client->chosen_mech << " from " <<
@@ -1592,8 +1604,7 @@ void Server::handleCommand_SrpBytesA(NetworkPacket* pkt)
 
        client->chosen_mech = chosen;
 
-       std::string salt;
-       std::string verifier;
+       std::string salt, verifier;
 
        if (based_on == 0) {
 
@@ -1625,6 +1636,7 @@ void Server::handleCommand_SrpBytesA(NetworkPacket* pkt)
                        << std::endl;
                if (wantSudo) {
                        DenySudoAccess(peer_id);
+                       client->resetChosenMech();
                        return;
                }
 
@@ -1642,10 +1654,10 @@ void Server::handleCommand_SrpBytesM(NetworkPacket* pkt)
        session_t peer_id = pkt->getPeerId();
        RemoteClient *client = getClient(peer_id, CS_Invalid);
        ClientState cstate = client->getState();
-       std::string addr_s = getPeerAddress(pkt->getPeerId()).serializeString();
-       std::string playername = client->getName();
+       const std::string addr_s = client->getAddress().serializeString();
+       const std::string playername = client->getName();
 
-       bool wantSudo = (cstate == CS_Active);
+       const bool wantSudo = (cstate == CS_Active);
 
        verbosestream << "Server: Received TOSERVER_SRP_BYTES_M." << std::endl;
 
@@ -1691,6 +1703,7 @@ void Server::handleCommand_SrpBytesM(NetworkPacket* pkt)
                                << " tried to change their password, but supplied wrong"
                                << " (SRP) password for authentication." << std::endl;
                        DenySudoAccess(peer_id);
+                       client->resetChosenMech();
                        return;
                }
 
@@ -1704,8 +1717,7 @@ void Server::handleCommand_SrpBytesM(NetworkPacket* pkt)
        if (client->create_player_on_auth_success) {
                m_script->createAuth(playername, client->enc_pwd);
 
-               std::string checkpwd; // not used, but needed for passing something
-               if (!m_script->getAuth(playername, &checkpwd, NULL)) {
+               if (!m_script->getAuth(playername, nullptr, nullptr)) {
                        errorstream << "Server: " << playername <<
                                " cannot be authenticated (auth handler does not work?)" <<
                                std::endl;
index 94a9f4180389636dbdb70c908f3d960e582c8a29..df15c89ba68c0a5499c2b07285ef0704fdbc6eab 100644 (file)
@@ -23,14 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <iostream>
 #include <cstdlib>
 #include <cstring>
-#include <cerrno>
-#include <sstream>
 #include <iomanip>
 #include "util/string.h"
 #include "util/numeric.h"
 #include "constants.h"
 #include "debug.h"
-#include "settings.h"
 #include "log.h"
 
 #ifdef _WIN32
@@ -42,9 +39,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #define LAST_SOCKET_ERR() WSAGetLastError()
-typedef SOCKET socket_t;
+#define SOCKET_ERR_STR(e) itos(e)
 typedef int socklen_t;
 #else
+#include <cerrno>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -53,7 +51,7 @@ typedef int socklen_t;
 #include <unistd.h>
 #include <arpa/inet.h>
 #define LAST_SOCKET_ERR() (errno)
-typedef int socket_t;
+#define SOCKET_ERR_STR(e) strerror(e)
 #endif
 
 // Set to true to enable verbose debug output
@@ -113,7 +111,7 @@ bool UDPSocket::init(bool ipv6, bool noExceptions)
                }
 
                throw SocketException(std::string("Failed to create socket: error ") +
-                                     itos(LAST_SOCKET_ERR()));
+                                     SOCKET_ERR_STR(LAST_SOCKET_ERR()));
        }
 
        setTimeoutMs(0);
@@ -153,40 +151,40 @@ void UDPSocket::Bind(Address addr)
        }
 
        if (addr.getFamily() != m_addr_family) {
-               static const char *errmsg =
+               const char *errmsg =
                                "Socket and bind address families do not match";
                errorstream << "Bind failed: " << errmsg << std::endl;
                throw SocketException(errmsg);
        }
 
+       int ret = 0;
+
        if (m_addr_family == AF_INET6) {
                struct sockaddr_in6 address;
                memset(&address, 0, sizeof(address));
 
-               address = addr.getAddress6();
                address.sin6_family = AF_INET6;
+               address.sin6_addr = addr.getAddress6();
                address.sin6_port = htons(addr.getPort());
 
-               if (bind(m_handle, (const struct sockaddr *)&address,
-                                   sizeof(struct sockaddr_in6)) < 0) {
-                       dstream << (int)m_handle << ": Bind failed: " << strerror(errno)
-                               << std::endl;
-                       throw SocketException("Failed to bind socket");
-               }
+               ret = bind(m_handle, (const struct sockaddr *) &address,
+                               sizeof(struct sockaddr_in6));
        } else {
                struct sockaddr_in address;
                memset(&address, 0, sizeof(address));
 
-               address = addr.getAddress();
                address.sin_family = AF_INET;
+               address.sin_addr = addr.getAddress();
                address.sin_port = htons(addr.getPort());
 
-               if (bind(m_handle, (const struct sockaddr *)&address,
-                                   sizeof(struct sockaddr_in)) < 0) {
-                       dstream << (int)m_handle << ": Bind failed: " << strerror(errno)
-                               << std::endl;
-                       throw SocketException("Failed to bind socket");
-               }
+               ret = bind(m_handle, (const struct sockaddr *) &address,
+                       sizeof(struct sockaddr_in));
+       }
+
+       if (ret < 0) {
+               dstream << (int)m_handle << ": Bind failed: "
+                       << SOCKET_ERR_STR(LAST_SOCKET_ERR()) << std::endl;
+               throw SocketException("Failed to bind socket");
        }
 }
 
@@ -200,7 +198,7 @@ void UDPSocket::Send(const Address &destination, const void *data, int size)
        if (socket_enable_debug_output) {
                // Print packet destination and size
                dstream << (int)m_handle << " -> ";
-               destination.print(&dstream);
+               destination.print(dstream);
                dstream << ", size=" << size;
 
                // Print packet contents
@@ -233,13 +231,19 @@ void UDPSocket::Send(const Address &destination, const void *data, int size)
 
        int sent;
        if (m_addr_family == AF_INET6) {
-               struct sockaddr_in6 address = destination.getAddress6();
+               struct sockaddr_in6 address = {};
+               address.sin6_family = AF_INET6;
+               address.sin6_addr = destination.getAddress6();
                address.sin6_port = htons(destination.getPort());
+
                sent = sendto(m_handle, (const char *)data, size, 0,
                                (struct sockaddr *)&address, sizeof(struct sockaddr_in6));
        } else {
-               struct sockaddr_in address = destination.getAddress();
+               struct sockaddr_in address = {};
+               address.sin_family = AF_INET;
+               address.sin_addr = destination.getAddress();
                address.sin_port = htons(destination.getPort());
+
                sent = sendto(m_handle, (const char *)data, size, 0,
                                (struct sockaddr *)&address, sizeof(struct sockaddr_in));
        }
@@ -267,9 +271,9 @@ int UDPSocket::Receive(Address &sender, void *data, int size)
                        return -1;
 
                u16 address_port = ntohs(address.sin6_port);
-               IPv6AddressBytes bytes;
-               memcpy(bytes.bytes, address.sin6_addr.s6_addr, 16);
-               sender = Address(&bytes, address_port);
+               const auto *bytes = reinterpret_cast<IPv6AddressBytes*>
+                       (address.sin6_addr.s6_addr);
+               sender = Address(bytes, address_port);
        } else {
                struct sockaddr_in address;
                memset(&address, 0, sizeof(address));
@@ -291,7 +295,7 @@ int UDPSocket::Receive(Address &sender, void *data, int size)
        if (socket_enable_debug_output) {
                // Print packet sender and size
                dstream << (int)m_handle << " <- ";
-               sender.print(&dstream);
+               sender.print(dstream);
                dstream << ", size=" << received;
 
                // Print packet contents
@@ -341,7 +345,12 @@ bool UDPSocket::WaitData(int timeout_ms)
        if (result == 0)
                return false;
 
-       if (result < 0 && (errno == EINTR || errno == EBADF)) {
+       int e = LAST_SOCKET_ERR();
+#ifdef _WIN32
+       if (result < 0 && (e == WSAEINTR || e == WSAEBADF)) {
+#else
+       if (result < 0 && (e == EINTR || e == EBADF)) {
+#endif
                // N.B. select() fails when sockets are destroyed on Connection's dtor
                // with EBADF.  Instead of doing tricky synchronization, allow this
                // thread to exit but don't throw an exception.
@@ -349,18 +358,9 @@ bool UDPSocket::WaitData(int timeout_ms)
        }
 
        if (result < 0) {
-               dstream << m_handle << ": Select failed: " << strerror(errno)
+               dstream << (int)m_handle << ": Select failed: " << SOCKET_ERR_STR(e)
                        << std::endl;
 
-#ifdef _WIN32
-               int e = WSAGetLastError();
-               dstream << (int)m_handle << ": WSAGetLastError()=" << e << std::endl;
-               if (e == 10004 /* WSAEINTR */ || e == 10009 /* WSAEBADF */) {
-                       infostream << "Ignoring WSAEINTR/WSAEBADF." << std::endl;
-                       return false;
-               }
-#endif
-
                throw SocketException("Select failed");
        } else if (!FD_ISSET(m_handle, &readset)) {
                // No data
index e0e76f4c2f176a1e8d21ecb974d688a1f0c2d402..d34186b443c348cdc8a70fc397b2b647e67b6940 100644 (file)
@@ -19,18 +19,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #pragma once
 
-#ifdef _WIN32
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
 #include <ostream>
 #include <cstring>
 #include "address.h"
@@ -53,8 +41,6 @@ class UDPSocket
 
        bool init(bool ipv6, bool noExceptions = false);
 
-       // void Close();
-       // bool IsOpen();
        void Send(const Address &destination, const void *data, int size);
        // Returns -1 if there is no data
        int Receive(Address &sender, void *data, int size);
index f27a8154b3ad5f9e8e701244375d2764d07712ad..2b8ebd77393c8ace40479fc9afb65d8ff5f70e1f 100644 (file)
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nameidmapping.h"
 #include "util/numeric.h"
 #include "util/serialize.h"
+#include "util/string.h"
 #include "exceptions.h"
 #include "debug.h"
 #include "gamedef.h"
@@ -207,7 +208,28 @@ void TileDef::serialize(std::ostream &os, u16 protocol_version) const
        u8 version = 6;
        writeU8(os, version);
 
-       os << serializeString16(name);
+       if (protocol_version > 39) {
+               os << serializeString16(name);
+       } else {
+               // Before f018737, TextureSource::getTextureAverageColor did not handle
+               // missing textures. "[png" can be used as base texture, but is not known
+               // on older clients. Hence use "blank.png" to avoid this problem.
+               // To be forward-compatible with future base textures/modifiers,
+               // we apply the same prefix to any texture beginning with [,
+               // except for the ones that are supported on older clients.
+               bool pass_through = true;
+
+               if (!name.empty() && name[0] == '[') {
+                       pass_through = str_starts_with(name, "[combine:") ||
+                               str_starts_with(name, "[inventorycube{") ||
+                               str_starts_with(name, "[lowpart:");
+               }
+
+               if (pass_through)
+                       os << serializeString16(name);
+               else
+                       os << serializeString16("blank.png^" + name);
+       }
        animation.serialize(os, version);
        bool has_scale = scale > 0;
        u16 flags = 0;
@@ -403,6 +425,8 @@ void ContentFeatures::reset()
        palette_name = "";
        palette = NULL;
        node_dig_prediction = "air";
+       move_resistance = 0;
+       liquid_move_physics = false;
 }
 
 void ContentFeatures::setAlphaFromLegacy(u8 legacy_alpha)
@@ -440,7 +464,12 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
        writeU16(os, groups.size());
        for (const auto &group : groups) {
                os << serializeString16(group.first);
-               writeS16(os, group.second);
+               if (protocol_version < 41 && group.first.compare("bouncy") == 0) {
+                       // Old clients may choke on negative bouncy value
+                       writeS16(os, abs(group.second));
+               } else {
+                       writeS16(os, group.second);
+               }
        }
        writeU8(os, param_type);
        writeU8(os, param_type_2);
@@ -489,7 +518,16 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
        writeU32(os, damage_per_second);
 
        // liquid
-       writeU8(os, liquid_type);
+       LiquidType liquid_type_bc = liquid_type;
+       if (protocol_version <= 39) {
+               // Since commit 7f25823, liquid drawtypes can be used even with LIQUID_NONE
+               // solution: force liquid type accordingly to accepted values
+               if (drawtype == NDT_LIQUID)
+                       liquid_type_bc = LIQUID_SOURCE;
+               else if (drawtype == NDT_FLOWINGLIQUID)
+                       liquid_type_bc = LIQUID_FLOWING;
+       }
+       writeU8(os, liquid_type_bc);
        os << serializeString16(liquid_alternative_flowing);
        os << serializeString16(liquid_alternative_source);
        writeU8(os, liquid_viscosity);
@@ -512,9 +550,12 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
        writeU8(os, legacy_facedir_simple);
        writeU8(os, legacy_wallmounted);
 
+       // new attributes
        os << serializeString16(node_dig_prediction);
        writeU8(os, leveled_max);
        writeU8(os, alpha);
+       writeU8(os, move_resistance);
+       writeU8(os, liquid_move_physics);
 }
 
 void ContentFeatures::deSerialize(std::istream &is)
@@ -584,9 +625,11 @@ void ContentFeatures::deSerialize(std::istream &is)
 
        // liquid
        liquid_type = (enum LiquidType) readU8(is);
+       liquid_move_physics = liquid_type != LIQUID_NONE;
        liquid_alternative_flowing = deSerializeString16(is);
        liquid_alternative_source = deSerializeString16(is);
        liquid_viscosity = readU8(is);
+       move_resistance = liquid_viscosity; // set default move_resistance
        liquid_renewable = readU8(is);
        liquid_range = readU8(is);
        drowning = readU8(is);
@@ -618,6 +661,16 @@ void ContentFeatures::deSerialize(std::istream &is)
                if (is.eof())
                        throw SerializationError("");
                alpha = static_cast<enum AlphaMode>(tmp);
+
+               tmp = readU8(is);
+               if (is.eof())
+                       throw SerializationError("");
+               move_resistance = tmp;
+
+               tmp = readU8(is);
+               if (is.eof())
+                       throw SerializationError("");
+               liquid_move_physics = tmp;
        } catch(SerializationError &e) {};
 }
 
@@ -634,7 +687,7 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer,
        bool has_scale = tiledef.scale > 0;
        bool use_autoscale = tsettings.autoscale_mode == AUTOSCALE_FORCE ||
                (tsettings.autoscale_mode == AUTOSCALE_ENABLE && !has_scale);
-       if (use_autoscale) {
+       if (use_autoscale && layer->texture) {
                auto texture_size = layer->texture->getOriginalSize();
                float base_size = tsettings.node_texture_size;
                float size = std::fmin(texture_size.Width, texture_size.Height);
@@ -670,6 +723,7 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer,
        // Animation parameters
        int frame_count = 1;
        if (layer->material_flags & MATERIAL_FLAG_ANIMATION) {
+               assert(layer->texture);
                int frame_length_ms;
                tiledef.animation.determineParams(layer->texture->getOriginalSize(),
                                &frame_count, &frame_length_ms, NULL);
@@ -680,14 +734,13 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer,
        if (frame_count == 1) {
                layer->material_flags &= ~MATERIAL_FLAG_ANIMATION;
        } else {
-               std::ostringstream os(std::ios::binary);
-               if (!layer->frames) {
+               assert(layer->texture);
+               if (!layer->frames)
                        layer->frames = new std::vector<FrameSpec>();
-               }
                layer->frames->resize(frame_count);
 
+               std::ostringstream os(std::ios::binary);
                for (int i = 0; i < frame_count; i++) {
-
                        FrameSpec frame;
 
                        os.str("");
@@ -779,8 +832,10 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
        TileDef tdef[6];
        for (u32 j = 0; j < 6; j++) {
                tdef[j] = tiledef[j];
-               if (tdef[j].name.empty())
-                       tdef[j].name = "unknown_node.png";
+               if (tdef[j].name.empty()) {
+                       tdef[j].name = "no_texture.png";
+                       tdef[j].backface_culling = false;
+               }
        }
        // also the overlay tiles
        TileDef tdef_overlay[6];
@@ -788,8 +843,9 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
                tdef_overlay[j] = tiledef_overlay[j];
        // also the special tiles
        TileDef tdef_spec[6];
-       for (u32 j = 0; j < CF_SPECIAL_COUNT; j++)
+       for (u32 j = 0; j < CF_SPECIAL_COUNT; j++) {
                tdef_spec[j] = tiledef_special[j];
+       }
 
        bool is_liquid = false;
 
@@ -1035,6 +1091,10 @@ void NodeDefManager::clear()
        {
                ContentFeatures f;
                f.name = "unknown";
+               TileDef unknownTile;
+               unknownTile.name = "unknown_node.png";
+               for (int t = 0; t < 6; t++)
+                       f.tiledef[t] = unknownTile;
                // Insert directly into containers
                content_t c = CONTENT_UNKNOWN;
                m_content_features[c] = f;
index 8a6d88071f1fe31935c46a1929b41509f6704326..f90caff8aea500daa4f59271cf1edb0b3d3881dc 100644 (file)
@@ -376,11 +376,15 @@ struct ContentFeatures
        u32 damage_per_second;
        // client dig prediction
        std::string node_dig_prediction;
+       // how slow players move through
+       u8 move_resistance = 0;
 
        // --- LIQUID PROPERTIES ---
 
        // Whether the node is non-liquid, source liquid or flowing liquid
        enum LiquidType liquid_type;
+       // If true, movement (e.g. of players) inside this node is liquid-like.
+       bool liquid_move_physics;
        // If the content is liquid, this is the flowing version of the liquid.
        std::string liquid_alternative_flowing;
        content_t liquid_alternative_flowing_id;
@@ -474,6 +478,12 @@ struct ContentFeatures
                return (liquid_alternative_flowing_id == f.liquid_alternative_flowing_id);
        }
 
+       bool lightingEquivalent(const ContentFeatures &other) const {
+               return light_propagates == other.light_propagates
+                               && sunlight_propagates == other.sunlight_propagates
+                               && light_source == other.light_source;
+       }
+
        int getGroup(const std::string &group) const
        {
                return itemgroup_get(groups, group);
index a10efa3c4c110e0b1d10ec1fac0f03d0e838b124..2f4de6855ac0afb1331c9a818f3519fdc1b18cea 100644 (file)
@@ -312,51 +312,6 @@ float noise2d_perlin(float x, float y, s32 seed,
 }
 
 
-float noise2d_perlin_abs(float x, float y, s32 seed,
-       int octaves, float persistence, bool eased)
-{
-       float a = 0;
-       float f = 1.0;
-       float g = 1.0;
-       for (int i = 0; i < octaves; i++) {
-               a += g * std::fabs(noise2d_gradient(x * f, y * f, seed + i, eased));
-               f *= 2.0;
-               g *= persistence;
-       }
-       return a;
-}
-
-
-float noise3d_perlin(float x, float y, float z, s32 seed,
-       int octaves, float persistence, bool eased)
-{
-       float a = 0;
-       float f = 1.0;
-       float g = 1.0;
-       for (int i = 0; i < octaves; i++) {
-               a += g * noise3d_gradient(x * f, y * f, z * f, seed + i, eased);
-               f *= 2.0;
-               g *= persistence;
-       }
-       return a;
-}
-
-
-float noise3d_perlin_abs(float x, float y, float z, s32 seed,
-       int octaves, float persistence, bool eased)
-{
-       float a = 0;
-       float f = 1.0;
-       float g = 1.0;
-       for (int i = 0; i < octaves; i++) {
-               a += g * std::fabs(noise3d_gradient(x * f, y * f, z * f, seed + i, eased));
-               f *= 2.0;
-               g *= persistence;
-       }
-       return a;
-}
-
-
 float contour(float v)
 {
        v = std::fabs(v);
index 854781731b9cc19920e963d5d71e0da167aaf600..e4a9ed6c76013130dadb12d5adb1bb6deadfac26 100644 (file)
@@ -224,15 +224,6 @@ float noise3d_gradient(float x, float y, float z, s32 seed, bool eased=false);
 float noise2d_perlin(float x, float y, s32 seed,
                int octaves, float persistence, bool eased=true);
 
-float noise2d_perlin_abs(float x, float y, s32 seed,
-               int octaves, float persistence, bool eased=true);
-
-float noise3d_perlin(float x, float y, float z, s32 seed,
-               int octaves, float persistence, bool eased=false);
-
-float noise3d_perlin_abs(float x, float y, float z, s32 seed,
-               int octaves, float persistence, bool eased=false);
-
 inline float easeCurve(float t)
 {
        return t * t * t * (t * (6.f * t - 15.f) + 10.f);
index db06f89300a245b221998def46b3606e861a0471..c7f6becf0a887b5029929fcb3bed9c3357a6a2a0 100644 (file)
@@ -28,7 +28,7 @@ static const video::SColor NULL_BGCOLOR{0, 1, 1, 1};
 
 ObjectProperties::ObjectProperties()
 {
-       textures.emplace_back("unknown_object.png");
+       textures.emplace_back("no_texture.png");
        colors.emplace_back(255,255,255,255);
 }
 
index 13b79da0451e3a9db3e44df1ac5950b66e4f4399..789d852eab325c12e09083ae77458d387190552a 100644 (file)
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "player.h"
 
+#include <cmath>
 #include "threading/mutex_auto_lock.h"
 #include "util/numeric.h"
 #include "hud.h"
@@ -70,7 +71,7 @@ Player::Player(const char *name, IItemDefManager *idef):
                HUD_FLAG_HOTBAR_VISIBLE    | HUD_FLAG_HEALTHBAR_VISIBLE |
                HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE |
                HUD_FLAG_BREATHBAR_VISIBLE | HUD_FLAG_MINIMAP_VISIBLE   |
-               HUD_FLAG_MINIMAP_RADAR_VISIBLE;
+               HUD_FLAG_MINIMAP_RADAR_VISIBLE | HUD_FLAG_BASIC_DEBUG;
 
        hud_hotbar_itemcount = HUD_HOTBAR_ITEMCOUNT_DEFAULT;
 
@@ -159,6 +160,64 @@ void Player::clearHud()
        }
 }
 
+#ifndef SERVER
+
+u32 PlayerControl::getKeysPressed() const
+{
+       u32 keypress_bits =
+               ( (u32)(jump  & 1) << 4) |
+               ( (u32)(aux1  & 1) << 5) |
+               ( (u32)(sneak & 1) << 6) |
+               ( (u32)(dig   & 1) << 7) |
+               ( (u32)(place & 1) << 8) |
+               ( (u32)(zoom  & 1) << 9)
+       ;
+
+       // If any direction keys are pressed pass those through
+       if (direction_keys != 0)
+       {
+               keypress_bits |= direction_keys;
+       }
+       // Otherwise set direction keys based on joystick movement (for mod compatibility)
+       else if (isMoving())
+       {
+               float abs_d;
+
+               // (absolute value indicates forward / backward)
+               abs_d = abs(movement_direction);
+               if (abs_d < 3.0f / 8.0f * M_PI)
+                       keypress_bits |= (u32)1; // Forward
+               if (abs_d > 5.0f / 8.0f * M_PI)
+                       keypress_bits |= (u32)1 << 1; // Backward
+
+               // rotate entire coordinate system by 90 degree
+               abs_d = movement_direction + M_PI_2;
+               if (abs_d >= M_PI)
+                       abs_d -= 2 * M_PI;
+               abs_d = abs(abs_d);
+               // (value now indicates left / right)
+               if (abs_d < 3.0f / 8.0f * M_PI)
+                       keypress_bits |= (u32)1 << 2; // Left
+               if (abs_d > 5.0f / 8.0f * M_PI)
+                       keypress_bits |= (u32)1 << 3; // Right
+       }
+
+       return keypress_bits;
+}
+
+#endif
+
+void PlayerControl::unpackKeysPressed(u32 keypress_bits)
+{
+       direction_keys = keypress_bits & 0xf;
+       jump  = keypress_bits & (1 << 4);
+       aux1  = keypress_bits & (1 << 5);
+       sneak = keypress_bits & (1 << 6);
+       dig   = keypress_bits & (1 << 7);
+       place = keypress_bits & (1 << 8);
+       zoom  = keypress_bits & (1 << 9);
+}
+
 void PlayerSettings::readGlobalSettings()
 {
        freecam = g_settings->getBool("freecam");
index 8f7b0a3fecac53732f5ae9f80a459481f1fa72b1..0216cfe9cbbc89e8c012176bbe7b05b0ce2fd8fa 100644 (file)
@@ -49,18 +49,18 @@ struct PlayerControl
        PlayerControl() = default;
 
        PlayerControl(
-               bool a_jump,
-               bool a_aux1,
-               bool a_sneak,
+               bool a_up, bool a_down, bool a_left, bool a_right,
+               bool a_jump, bool a_aux1, bool a_sneak,
                bool a_zoom,
-               bool a_dig,
-               bool a_place,
-               float a_pitch,
-               float a_yaw,
-               float a_movement_speed,
-               float a_movement_direction
+               bool a_dig, bool a_place,
+               float a_pitch, float a_yaw,
+               float a_movement_speed, float a_movement_direction
        )
        {
+               // Encode direction keys into a single value so nobody uses it accidentally
+               // as movement_{speed,direction} is supposed to be the source of truth.
+               direction_keys = (a_up&1) | ((a_down&1) << 1) |
+                       ((a_left&1) << 2) | ((a_right&1) << 3);
                jump = a_jump;
                aux1 = a_aux1;
                sneak = a_sneak;
@@ -72,15 +72,26 @@ struct PlayerControl
                movement_speed = a_movement_speed;
                movement_direction = a_movement_direction;
        }
+
+#ifndef SERVER
+       // For client use
+       u32 getKeysPressed() const;
+       inline bool isMoving() const { return movement_speed > 0.001f; }
+#endif
+
+       // For server use
+       void unpackKeysPressed(u32 keypress_bits);
+
+       u8 direction_keys = 0;
        bool jump = false;
        bool aux1 = false;
        bool sneak = false;
        bool zoom = false;
        bool dig = false;
        bool place = false;
+       // Note: These four are NOT available on the server
        float pitch = 0.0f;
        float yaw = 0.0f;
-       // Note: These two are NOT available on the server
        float movement_speed = 0.0f;
        float movement_direction = 0.0f;
 };
@@ -190,8 +201,6 @@ class Player
                return m_fov_override_spec;
        }
 
-       u32 keyPressed = 0;
-
        HudElement* getHud(u32 id);
        u32         addHud(HudElement* hud);
        HudElement* removeHud(u32 id);
index 4c87bddee0cf0b2a65be7a047262fa68d928af46..09627431c7e8bd501498d9ef147b92c93da787a4 100644 (file)
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        #include <algorithm>
        #include <shlwapi.h>
        #include <shellapi.h>
+       #include <mmsystem.h>
 #endif
 #if !defined(_WIN32)
        #include <unistd.h>
@@ -69,6 +70,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <cstdarg>
 #include <cstdio>
 
+#if !defined(SERVER) && defined(_WIN32)
+// On Windows export some driver-specific variables to encourage Minetest to be
+// executed on the discrete GPU in case of systems with two. Portability is fun.
+extern "C" {
+       __declspec(dllexport) DWORD NvOptimusEnablement = 1;
+       __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1;
+}
+#endif
+
 namespace porting
 {
 
@@ -598,7 +608,7 @@ void initializePaths()
        // First try $XDG_CACHE_HOME/PROJECT_NAME
        const char *cache_dir = getenv("XDG_CACHE_HOME");
        const char *home_dir = getenv("HOME");
-       if (cache_dir) {
+       if (cache_dir && cache_dir[0] != '\0') {
                path_cache = std::string(cache_dir) + DIR_DELIM + PROJECT_NAME;
        } else if (home_dir) {
                // Then try $HOME/.cache/PROJECT_NAME
@@ -766,6 +776,9 @@ bool open_directory(const std::string &path)
 
 inline double get_perf_freq()
 {
+       // Also use this opportunity to enable high-res timers
+       timeBeginPeriod(1);
+
        LARGE_INTEGER freq;
        QueryPerformanceFrequency(&freq);
        return freq.QuadPart;
index 29e95b8ca984e5d5a76681110d54c74c70f81262..c71fe5ad88e1c733de7a9a7afceee4d7163139db 100644 (file)
@@ -152,48 +152,35 @@ static std::string javaStringToUTF8(jstring js)
        return str;
 }
 
-// Calls static method if obj is NULL
-static std::string getAndroidPath(
-               jclass cls, jobject obj, jmethodID mt_getAbsPath, const char *getter)
-{
-       // Get getter method
-       jmethodID mt_getter;
-       if (obj)
-               mt_getter = jnienv->GetMethodID(cls, getter, "()Ljava/io/File;");
-       else
-               mt_getter = jnienv->GetStaticMethodID(cls, getter, "()Ljava/io/File;");
-
-       // Call getter
-       jobject ob_file;
-       if (obj)
-               ob_file = jnienv->CallObjectMethod(obj, mt_getter);
-       else
-               ob_file = jnienv->CallStaticObjectMethod(cls, mt_getter);
-
-       // Call getAbsolutePath
-       auto js_path = (jstring) jnienv->CallObjectMethod(ob_file, mt_getAbsPath);
-
-       return javaStringToUTF8(js_path);
-}
-
 void initializePathsAndroid()
 {
-       // Get Environment class
-       jclass cls_Env = jnienv->FindClass("android/os/Environment");
-       // Get File class
-       jclass cls_File = jnienv->FindClass("java/io/File");
-       // Get getAbsolutePath method
-       jmethodID mt_getAbsPath = jnienv->GetMethodID(cls_File,
-                               "getAbsolutePath", "()Ljava/lang/String;");
-       std::string path_storage = getAndroidPath(cls_Env, nullptr,
-                               mt_getAbsPath, "getExternalStorageDirectory");
-
-       path_user    = path_storage + DIR_DELIM + PROJECT_NAME_C;
-       path_share   = path_storage + DIR_DELIM + PROJECT_NAME_C;
-       path_locale  = path_share + DIR_DELIM + "locale";
-       path_cache   = getAndroidPath(nativeActivity,
-                       app_global->activity->clazz, mt_getAbsPath, "getCacheDir");
-       migrateCachePath();
+       // Set user and share paths
+       {
+               jmethodID getUserDataPath = jnienv->GetMethodID(nativeActivity,
+                               "getUserDataPath", "()Ljava/lang/String;");
+               FATAL_ERROR_IF(getUserDataPath==nullptr,
+                               "porting::initializePathsAndroid unable to find Java getUserDataPath method");
+               jobject result = jnienv->CallObjectMethod(app_global->activity->clazz, getUserDataPath);
+               const char *javachars = jnienv->GetStringUTFChars((jstring) result, nullptr);
+               path_user = javachars;
+               path_share = javachars;
+               path_locale  = path_share + DIR_DELIM + "locale";
+               jnienv->ReleaseStringUTFChars((jstring) result, javachars);
+       }
+
+       // Set cache path
+       {
+               jmethodID getCachePath = jnienv->GetMethodID(nativeActivity,
+                               "getCachePath", "()Ljava/lang/String;");
+               FATAL_ERROR_IF(getCachePath==nullptr,
+                               "porting::initializePathsAndroid unable to find Java getCachePath method");
+               jobject result = jnienv->CallObjectMethod(app_global->activity->clazz, getCachePath);
+               const char *javachars = jnienv->GetStringUTFChars((jstring) result, nullptr);
+               path_cache = javachars;
+               jnienv->ReleaseStringUTFChars((jstring) result, javachars);
+
+               migrateCachePath();
+       }
 }
 
 void showInputDialog(const std::string &acceptButton, const std::string &hint,
index 925ad001b987de64d8e633972a4baf7757b6fc49..20be7a8c81f39a428b3a1aa0649aa5eb30e3abea 100644 (file)
@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 /*
        RemotePlayer
 */
+
 // static config cache for remoteplayer
 bool RemotePlayer::m_setting_cache_loaded = false;
 float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f;
@@ -46,6 +47,7 @@ RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef):
                        g_settings->getU16("chat_message_limit_trigger_kick");
                RemotePlayer::m_setting_cache_loaded = true;
        }
+
        movement_acceleration_default   = g_settings->getFloat("movement_acceleration_default")   * BS;
        movement_acceleration_air       = g_settings->getFloat("movement_acceleration_air")       * BS;
        movement_acceleration_fast      = g_settings->getFloat("movement_acceleration_fast")      * BS;
@@ -59,32 +61,16 @@ RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef):
        movement_liquid_sink            = g_settings->getFloat("movement_liquid_sink")            * BS;
        movement_gravity                = g_settings->getFloat("movement_gravity")                * BS;
 
-       // copy defaults
-       m_cloud_params.density = 0.4f;
-       m_cloud_params.color_bright = video::SColor(229, 240, 240, 255);
-       m_cloud_params.color_ambient = video::SColor(255, 0, 0, 0);
-       m_cloud_params.height = 120.0f;
-       m_cloud_params.thickness = 16.0f;
-       m_cloud_params.speed = v2f(0.0f, -2.0f);
-
        // Skybox defaults:
-
-       SkyboxDefaults sky_defaults;
-
-       m_skybox_params.sky_color = sky_defaults.getSkyColorDefaults();
-       m_skybox_params.type = "regular";
-       m_skybox_params.clouds = true;
-       m_skybox_params.fog_sun_tint = video::SColor(255, 244, 125, 29);
-       m_skybox_params.fog_moon_tint = video::SColorf(0.5, 0.6, 0.8, 1).toSColor();
-       m_skybox_params.fog_tint_type = "default";
-
-       m_sun_params = sky_defaults.getSunDefaults();
-       m_moon_params = sky_defaults.getMoonDefaults();
-       m_star_params = sky_defaults.getStarDefaults();
+       m_cloud_params  = SkyboxDefaults::getCloudDefaults();
+       m_skybox_params = SkyboxDefaults::getSkyDefaults();
+       m_sun_params    = SkyboxDefaults::getSunDefaults();
+       m_moon_params   = SkyboxDefaults::getMoonDefaults();
+       m_star_params   = SkyboxDefaults::getStarDefaults();
 }
 
 
-const RemotePlayerChatResult RemotePlayer::canSendChatMessage()
+RemotePlayerChatResult RemotePlayer::canSendChatMessage()
 {
        // Rate limit messages
        u32 now = time(NULL);
index 8d086fc5a721d4c503fda2c19e10b4655da67530..0ab33adfe18e3d0a815941e757eab5029f7c72fb 100644 (file)
@@ -21,8 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #pragma once
 
 #include "player.h"
-#include "cloudparams.h"
 #include "skyparams.h"
+#include "lighting.h"
 
 class PlayerSAO;
 
@@ -47,7 +47,7 @@ class RemotePlayer : public Player
        PlayerSAO *getPlayerSAO() { return m_sao; }
        void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; }
 
-       const RemotePlayerChatResult canSendChatMessage();
+       RemotePlayerChatResult canSendChatMessage();
 
        void setHotbarItemcount(s32 hotbar_itemcount)
        {
@@ -126,12 +126,14 @@ class RemotePlayer : public Player
                *frame_speed = local_animation_speed;
        }
 
+       void setLighting(const Lighting &lighting) { m_lighting = lighting; }
+
+       const Lighting& getLighting() const { return m_lighting; }
+
        void setDirty(bool dirty) { m_dirty = true; }
 
        u16 protocol_version = 0;
-
-       // v1 for clients older than 5.1.0-dev
-       u16 formspec_version = 1;
+       u16 formspec_version = 0;
 
        session_t getPeerId() const { return m_peer_id; }
 
@@ -163,5 +165,7 @@ class RemotePlayer : public Player
        MoonParams m_moon_params;
        StarParams m_star_params;
 
+       Lighting m_lighting;
+
        session_t m_peer_id = PEER_ID_INEXISTENT;
 };
index 3cd9c7ce7c63c2e4ca748480dc7a2191924a1d99..b454e40c929c41c20f27b6782ae0dc940f1bdd8e 100644 (file)
@@ -483,6 +483,7 @@ const std::list<ActionRow> RollbackManager::actionRowsFromSelect(sqlite3_stmt* s
                row.actor     = sqlite3_column_int  (stmt, 0);
                row.timestamp = sqlite3_column_int64(stmt, 1);
                row.type      = sqlite3_column_int  (stmt, 2);
+               row.nodeMeta  = 0;
 
                if (row.type == RollbackAction::TYPE_MODIFY_INVENTORY_STACK) {
                        text = sqlite3_column_text (stmt, 3);
@@ -941,12 +942,6 @@ void RollbackManager::addAction(const RollbackAction & action)
        }
 }
 
-std::list<RollbackAction> RollbackManager::getEntriesSince(time_t first_time)
-{
-       flush();
-       return getActionsSince(first_time);
-}
-
 std::list<RollbackAction> RollbackManager::getNodeActors(v3s16 pos, int range,
                time_t seconds, int limit)
 {
index 1d9949d1520676094d5c548dc0a9dc3de8ee5f26..ff96e513f5453938cc4df0bcd4f73f3351801855 100644 (file)
@@ -46,7 +46,6 @@ class RollbackManager: public IRollbackManager
        void flush();
 
        void addAction(const RollbackAction & action);
-       std::list<RollbackAction> getEntriesSince(time_t first_time);
        std::list<RollbackAction> getNodeActors(v3s16 pos, int range,
                        time_t seconds, int limit);
        std::list<RollbackAction> getRevertActions(
index d07f6ab1be16be485536d713e7bec37ebed3cbb9..3e84b46c76a7a9d488154a96ddfe3c8d84cd53f0 100644 (file)
@@ -3,6 +3,7 @@ set(common_SCRIPT_COMMON_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/c_packer.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/helper.cpp
        PARENT_SCOPE)
 
index 8ca3a722fb505261977281155d5e661234ddd89d..0bdeaab9ee276a518bb926b01cd516f65cd0faa0 100644 (file)
@@ -751,6 +751,9 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index)
        // the slowest possible
        f.liquid_viscosity = getintfield_default(L, index,
                        "liquid_viscosity", f.liquid_viscosity);
+       // If move_resistance is not set explicitly,
+       // move_resistance is equal to liquid_viscosity
+       f.move_resistance = f.liquid_viscosity;
        f.liquid_range = getintfield_default(L, index,
                        "liquid_range", f.liquid_range);
        f.leveled = getintfield_default(L, index, "leveled", f.leveled);
@@ -854,6 +857,21 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index)
        getstringfield(L, index, "node_dig_prediction",
                f.node_dig_prediction);
 
+       // How much the node slows down players, ranging from 1 to 7,
+       // the higher, the slower.
+       f.move_resistance = getintfield_default(L, index,
+                       "move_resistance", f.move_resistance);
+
+       // Whether e.g. players in this node will have liquid movement physics
+       lua_getfield(L, index, "liquid_move_physics");
+       if(lua_isboolean(L, -1)) {
+               f.liquid_move_physics = lua_toboolean(L, -1);
+       } else if(lua_isnil(L, -1)) {
+               f.liquid_move_physics = f.liquid_type != LIQUID_NONE;
+       } else {
+               errorstream << "Field \"liquid_move_physics\": Invalid type!" << std::endl;
+       }
+       lua_pop(L, 1);
 }
 
 void push_content_features(lua_State *L, const ContentFeatures &c)
@@ -1004,6 +1022,10 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
        lua_setfield(L, -2, "legacy_wallmounted");
        lua_pushstring(L, c.node_dig_prediction.c_str());
        lua_setfield(L, -2, "node_dig_prediction");
+       lua_pushnumber(L, c.move_resistance);
+       lua_setfield(L, -2, "move_resistance");
+       lua_pushboolean(L, c.liquid_move_physics);
+       lua_setfield(L, -2, "liquid_move_physics");
 }
 
 /******************************************************************************/
@@ -1384,24 +1406,27 @@ void push_tool_capabilities(lua_State *L,
 }
 
 /******************************************************************************/
-void push_inventory(lua_State *L, Inventory *inventory)
+void push_inventory_list(lua_State *L, const InventoryList &invlist)
 {
-       if (! inventory)
-               throw SerializationError("Attempt to push nonexistant inventory");
-       std::vector<const InventoryList*> lists = inventory->getLists();
-       std::vector<const InventoryList*>::iterator iter = lists.begin();
+       push_items(L, invlist.getItems());
+}
+
+/******************************************************************************/
+void push_inventory_lists(lua_State *L, const Inventory &inv)
+{
+       const auto &lists = inv.getLists();
        lua_createtable(L, 0, lists.size());
-       for (; iter != lists.end(); iter++) {
-               const char* name = (*iter)->getName().c_str();
-               lua_pushstring(L, name);
-               push_inventory_list(L, inventory, name);
+       for(const InventoryList *list : lists) {
+               const std::string &name = list->getName();
+               lua_pushlstring(L, name.c_str(), name.size());
+               push_inventory_list(L, *list);
                lua_rawset(L, -3);
        }
 }
 
 /******************************************************************************/
 void read_inventory_list(lua_State *L, int tableindex,
-               Inventory *inv, const char *name, Server* srv, int forcesize)
+               Inventory *inv, const char *name, IGameDef *gdef, int forcesize)
 {
        if(tableindex < 0)
                tableindex = lua_gettop(L) + 1 + tableindex;
@@ -1413,7 +1438,7 @@ void read_inventory_list(lua_State *L, int tableindex,
        }
 
        // Get Lua-specified items to insert into the list
-       std::vector<ItemStack> items = read_items(L, tableindex,srv);
+       std::vector<ItemStack> items = read_items(L, tableindex, gdef);
        size_t listsize = (forcesize >= 0) ? forcesize : items.size();
 
        // Create or resize/clear list
@@ -1430,19 +1455,6 @@ void read_inventory_list(lua_State *L, int tableindex,
        }
 }
 
-void push_inventory_list(lua_State *L, Inventory *inv, const char *name)
-{
-       InventoryList *invlist = inv->getList(name);
-       if(invlist == NULL){
-               lua_pushnil(L);
-               return;
-       }
-       std::vector<ItemStack> items;
-       for(u32 i=0; i<invlist->getSize(); i++)
-               items.push_back(invlist->getItem(i));
-       push_items(L, items);
-}
-
 /******************************************************************************/
 struct TileAnimationParams read_animation_definition(lua_State *L, int index)
 {
@@ -1701,7 +1713,7 @@ void push_items(lua_State *L, const std::vector<ItemStack> &items)
 }
 
 /******************************************************************************/
-std::vector<ItemStack> read_items(lua_State *L, int index, Server *srv)
+std::vector<ItemStack> read_items(lua_State *L, int index, IGameDef *gdef)
 {
        if(index < 0)
                index = lua_gettop(L) + 1 + index;
@@ -1717,7 +1729,7 @@ std::vector<ItemStack> read_items(lua_State *L, int index, Server *srv)
                if (items.size() < (u32) key) {
                        items.resize(key);
                }
-               items[key - 1] = read_item(L, -1, srv->idef());
+               items[key - 1] = read_item(L, -1, gdef->idef());
                lua_pop(L, 1);
        }
        return items;
@@ -1768,24 +1780,19 @@ bool read_noiseparams(lua_State *L, int index, NoiseParams *np)
 void push_noiseparams(lua_State *L, NoiseParams *np)
 {
        lua_newtable(L);
-       push_float_string(L, np->offset);
-       lua_setfield(L, -2, "offset");
-       push_float_string(L, np->scale);
-       lua_setfield(L, -2, "scale");
-       push_float_string(L, np->persist);
-       lua_setfield(L, -2, "persistence");
-       push_float_string(L, np->lacunarity);
-       lua_setfield(L, -2, "lacunarity");
-       lua_pushnumber(L, np->seed);
-       lua_setfield(L, -2, "seed");
-       lua_pushnumber(L, np->octaves);
-       lua_setfield(L, -2, "octaves");
+       setfloatfield(L, -1, "offset",      np->offset);
+       setfloatfield(L, -1, "scale",       np->scale);
+       setfloatfield(L, -1, "persist",     np->persist);
+       setfloatfield(L, -1, "persistence", np->persist);
+       setfloatfield(L, -1, "lacunarity",  np->lacunarity);
+       setintfield(  L, -1, "seed",        np->seed);
+       setintfield(  L, -1, "octaves",     np->octaves);
 
        push_flags_string(L, flagdesc_noiseparams, np->flags,
                np->flags);
        lua_setfield(L, -2, "flags");
 
-       push_v3_float_string(L, np->spread);
+       push_v3f(L, np->spread);
        lua_setfield(L, -2, "spread");
 }
 
@@ -2042,6 +2049,12 @@ void push_hud_element(lua_State *L, HudElement *elem)
        lua_pushnumber(L, elem->number);
        lua_setfield(L, -2, "number");
 
+       if (elem->type == HUD_ELEM_WAYPOINT) {
+               // waypoints reuse the item field to store precision, precision = item - 1
+               lua_pushnumber(L, elem->item - 1);
+               lua_setfield(L, -2, "precision");
+       }
+       // push the item field for waypoints as well for backwards compatibility
        lua_pushnumber(L, elem->item);
        lua_setfield(L, -2, "item");
 
index 1aed7901e835c3db11afe04d29d397d8509d9289..a6b96c0122913cf5787297b9092d20265ab057e7 100644 (file)
@@ -55,10 +55,11 @@ struct ObjectProperties;
 struct SimpleSoundSpec;
 struct ServerSoundParams;
 class Inventory;
+class InventoryList;
 struct NodeBox;
 struct ContentFeatures;
 struct TileDef;
-class Server;
+class IGameDef;
 struct DigParams;
 struct HitParams;
 struct EnumString;
@@ -124,11 +125,12 @@ void               push_inventory          (lua_State *L,
                                               Inventory *inventory);
 
 void               push_inventory_list       (lua_State *L,
-                                              Inventory *inv,
-                                              const char *name);
+                                              const InventoryList &invlist);
+void               push_inventory_lists      (lua_State *L,
+                                              const Inventory &inv);
 void               read_inventory_list       (lua_State *L, int tableindex,
                                               Inventory *inv, const char *name,
-                                              Server *srv, int forcesize=-1);
+                                              IGameDef *gdef, int forcesize=-1);
 
 MapNode            readnode                  (lua_State *L, int index,
                                               const NodeDefManager *ndef);
@@ -168,7 +170,7 @@ void               push_items                (lua_State *L,
 
 std::vector<ItemStack> read_items            (lua_State *L,
                                               int index,
-                                              Server* srv);
+                                              IGameDef* gdef);
 
 void               push_soundspec            (lua_State *L,
                                               const SimpleSoundSpec &spec);
index 19734b913bf8349d40afa28090b445b05f77399b..b5ff52f73bcaf6572466b65cd3b20cd7d1f003f5 100644 (file)
@@ -52,32 +52,12 @@ if (value < F1000_MIN || value > F1000_MAX) { \
 
 
 /**
- * A helper which sets (if available) the vector metatable from builtin as metatable
- * for the table on top of the stack
+ * A helper which sets the vector metatable for the table on top of the stack
  */
 static void set_vector_metatable(lua_State *L)
 {
-       // get vector.metatable
-       lua_getglobal(L, "vector");
-       if (!lua_istable(L, -1)) {
-               // there is no global vector table
-               lua_pop(L, 1);
-               errorstream << "set_vector_metatable in c_converter.cpp: " <<
-                               "missing global vector table" << std::endl;
-               return;
-       }
-       lua_getfield(L, -1, "metatable");
-       // set the metatable
-       lua_setmetatable(L, -3);
-       // pop vector global
-       lua_pop(L, 1);
-}
-
-
-void push_float_string(lua_State *L, float value)
-{
-       auto str = ftos(value);
-       lua_pushstring(L, str.c_str());
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE);
+       lua_setmetatable(L, -2);
 }
 
 void push_v3f(lua_State *L, v3f p)
@@ -101,26 +81,6 @@ void push_v2f(lua_State *L, v2f p)
        lua_setfield(L, -2, "y");
 }
 
-void push_v3_float_string(lua_State *L, v3f p)
-{
-       lua_createtable(L, 0, 3);
-       push_float_string(L, p.X);
-       lua_setfield(L, -2, "x");
-       push_float_string(L, p.Y);
-       lua_setfield(L, -2, "y");
-       push_float_string(L, p.Z);
-       lua_setfield(L, -2, "z");
-}
-
-void push_v2_float_string(lua_State *L, v2f p)
-{
-       lua_createtable(L, 0, 2);
-       push_float_string(L, p.X);
-       lua_setfield(L, -2, "x");
-       push_float_string(L, p.Y);
-       lua_setfield(L, -2, "y");
-}
-
 v2s16 read_v2s16(lua_State *L, int index)
 {
        v2s16 p;
@@ -479,17 +439,9 @@ size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result
        Table field getters
 */
 
-#if defined(__MINGW32__) && !defined(__MINGW64__)
-/* MinGW 32-bit somehow crashes in the std::set destructor when this
- * variable is thread-local, so just don't do that. */
-static std::set<u64> warned_msgs;
-#endif
-
 bool check_field_or_nil(lua_State *L, int index, int type, const char *fieldname)
 {
-#if !defined(__MINGW32__) || defined(__MINGW64__)
        thread_local std::set<u64> warned_msgs;
-#endif
 
        int t = lua_type(L, index);
        if (t == LUA_TNIL)
index 6ad6f32121ecfd7950d10ff1695042e86e3d56d7..a14eb91861fabffd8bde61443ed02a6d4847e42b 100644 (file)
@@ -118,9 +118,6 @@ std::vector<aabb3f> read_aabb3f_vector  (lua_State *L, int index, f32 scale);
 size_t              read_stringlist     (lua_State *L, int index,
                                          std::vector<std::string> *result);
 
-void                push_float_string   (lua_State *L, float value);
-void                push_v3_float_string(lua_State *L, v3f p);
-void                push_v2_float_string(lua_State *L, v2f p);
 void                push_v2s16          (lua_State *L, v2s16 p);
 void                push_v2s32          (lua_State *L, v2s32 p);
 void                push_v3s16          (lua_State *L, v3s16 p);
index df82dba146ec7ddcb5d0becc7446b743e8c71e17..ddd2d184c5b320186846e7647326871f4dc9799b 100644 (file)
@@ -166,3 +166,17 @@ void log_deprecated(lua_State *L, std::string message, int stack_depth)
                infostream << script_get_backtrace(L) << std::endl;
 }
 
+void call_string_dump(lua_State *L, int idx)
+{
+       // Retrieve string.dump from insecure env to avoid it being tampered with
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
+       if (!lua_isnil(L, -1))
+               lua_getfield(L, -1, "string");
+       else
+               lua_getglobal(L, "string");
+       lua_getfield(L, -1, "dump");
+       lua_remove(L, -2); // remove _G
+       lua_remove(L, -2); // remove 'string' table
+       lua_pushvalue(L, idx);
+       lua_call(L, 1, 1);
+}
index ab2d7b975a89c6af2d923d016dd15772027d5abc..272a3994147b3307b140b8987b6e181c426aac04 100644 (file)
@@ -54,6 +54,10 @@ extern "C" {
 #define CUSTOM_RIDX_GLOBALS_BACKUP      (CUSTOM_RIDX_BASE + 1)
 #define CUSTOM_RIDX_CURRENT_MOD_NAME    (CUSTOM_RIDX_BASE + 2)
 #define CUSTOM_RIDX_BACKTRACE           (CUSTOM_RIDX_BASE + 3)
+#define CUSTOM_RIDX_HTTP_API_LUA        (CUSTOM_RIDX_BASE + 4)
+#define CUSTOM_RIDX_VECTOR_METATABLE    (CUSTOM_RIDX_BASE + 5)
+#define CUSTOM_RIDX_METATABLE_MAP       (CUSTOM_RIDX_BASE + 6)
+
 
 // Determine if CUSTOM_RIDX_SCRIPTAPI will hold a light or full userdata
 #if defined(__aarch64__) && USE_LUAJIT
@@ -136,3 +140,7 @@ DeprecatedHandlingMode get_deprecated_handling_mode();
  * @param stack_depth How far on the stack to the first user function (ie: not builtin or core)
  */
 void log_deprecated(lua_State *L, std::string message, int stack_depth = 1);
+
+// Safely call string.dump on a function value
+// (does not pop, leaves one value on stack)
+void call_string_dump(lua_State *L, int idx);
diff --git a/src/script/common/c_packer.cpp b/src/script/common/c_packer.cpp
new file mode 100644 (file)
index 0000000..ede00c7
--- /dev/null
@@ -0,0 +1,596 @@
+/*
+Minetest
+Copyright (C) 2022 sfan5 <sfan5@live.de>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <cstdio>
+#include <cstring>
+#include <cmath>
+#include <cassert>
+#include <unordered_set>
+#include <unordered_map>
+#include "c_packer.h"
+#include "c_internal.h"
+#include "log.h"
+#include "debug.h"
+#include "threading/mutex_auto_lock.h"
+
+extern "C" {
+#include <lauxlib.h>
+}
+
+//
+// Helpers
+//
+
+// convert negative index to absolute position on Lua stack
+static inline int absidx(lua_State *L, int idx)
+{
+       assert(idx < 0);
+       return lua_gettop(L) + idx + 1;
+}
+
+// does the type put anything into PackedInstr::sdata?
+static inline bool uses_sdata(int type)
+{
+       switch (type) {
+               case LUA_TSTRING:
+               case LUA_TFUNCTION:
+               case LUA_TUSERDATA:
+                       return true;
+               default:
+                       return false;
+       }
+}
+
+// does the type put anything into PackedInstr::<union>?
+static inline bool uses_union(int type)
+{
+       switch (type) {
+               case LUA_TNIL:
+               case LUA_TSTRING:
+               case LUA_TFUNCTION:
+                       return false;
+               default:
+                       return true;
+       }
+}
+
+static inline bool can_set_into(int ktype, int vtype)
+{
+       switch (ktype) {
+               case LUA_TNUMBER:
+                       return !uses_union(vtype);
+               case LUA_TSTRING:
+                       return !uses_sdata(vtype);
+               default:
+                       return false;
+       }
+}
+
+// is the key suitable for use with set_into?
+static inline bool suitable_key(lua_State *L, int idx)
+{
+       if (lua_type(L, idx) == LUA_TSTRING) {
+               // strings may not have a NULL byte (-> lua_setfield)
+               size_t len;
+               const char *str = lua_tolstring(L, idx, &len);
+               return strlen(str) == len;
+       } else {
+               assert(lua_type(L, idx) == LUA_TNUMBER);
+               // numbers must fit into an s32 and be integers (-> lua_rawseti)
+               lua_Number n = lua_tonumber(L, idx);
+               return std::floor(n) == n && n >= S32_MIN && n <= S32_MAX;
+       }
+}
+
+namespace {
+       // checks if you left any values on the stack, for debugging
+       class StackChecker {
+               lua_State *L;
+               int top;
+       public:
+               StackChecker(lua_State *L) : L(L), top(lua_gettop(L)) {}
+               ~StackChecker() {
+                       assert(lua_gettop(L) >= top);
+                       if (lua_gettop(L) > top) {
+                               rawstream << "Lua stack not cleaned up: "
+                                       << lua_gettop(L) << " != " << top
+                                       << " (false-positive if exception thrown)" << std::endl;
+                       }
+               }
+       };
+
+       // Since an std::vector may reallocate, this is the only safe way to keep
+       // a reference to a particular element.
+       template <typename T>
+       class VectorRef {
+               std::vector<T> *vec;
+               size_t idx;
+               VectorRef(std::vector<T> *vec, size_t idx) : vec(vec), idx(idx) {}
+       public:
+               constexpr VectorRef() : vec(nullptr), idx(0) {}
+               static VectorRef<T> front(std::vector<T> &vec) {
+                       return VectorRef(&vec, 0);
+               }
+               static VectorRef<T> back(std::vector<T> &vec) {
+                       return VectorRef(&vec, vec.size() - 1);
+               }
+               T &operator*() { return (*vec)[idx]; }
+               T *operator->() { return &(*vec)[idx]; }
+               operator bool() const { return vec != nullptr; }
+       };
+
+       struct Packer {
+               PackInFunc fin;
+               PackOutFunc fout;
+       };
+
+       typedef std::pair<std::string, Packer> PackerTuple;
+}
+
+static inline auto emplace(PackedValue &pv, s16 type)
+{
+       pv.i.emplace_back();
+       auto ref = VectorRef<PackedInstr>::back(pv.i);
+       ref->type = type;
+       // Initialize fields that may be left untouched
+       if (type == LUA_TTABLE) {
+               ref->uidata1 = 0;
+               ref->uidata2 = 0;
+       } else if (type == LUA_TUSERDATA) {
+               ref->ptrdata = nullptr;
+       } else if (type == INSTR_POP) {
+               ref->sidata2 = 0;
+       }
+       return ref;
+}
+
+//
+// Management of registered packers
+//
+
+static std::unordered_map<std::string, Packer> g_packers;
+static std::mutex g_packers_lock;
+
+void script_register_packer(lua_State *L, const char *regname,
+       PackInFunc fin, PackOutFunc fout)
+{
+       // Store away callbacks
+       {
+               MutexAutoLock autolock(g_packers_lock);
+               auto it = g_packers.find(regname);
+               if (it == g_packers.end()) {
+                       auto &ref = g_packers[regname];
+                       ref.fin = fin;
+                       ref.fout = fout;
+               } else {
+                       FATAL_ERROR_IF(it->second.fin != fin || it->second.fout != fout,
+                               "Packer registered twice with mismatching callbacks");
+               }
+       }
+
+       // Save metatable so we can identify instances later
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_METATABLE_MAP);
+       if (lua_isnil(L, -1)) {
+               lua_newtable(L);
+               lua_pushvalue(L, -1);
+               lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_METATABLE_MAP);
+       }
+
+       luaL_getmetatable(L, regname);
+       FATAL_ERROR_IF(lua_isnil(L, -1), "No metatable registered with that name");
+
+       // CUSTOM_RIDX_METATABLE_MAP contains { [metatable] = "regname", ... }
+       // check first
+       lua_pushstring(L, regname);
+       lua_rawget(L, -3);
+       if (!lua_isnil(L, -1)) {
+               FATAL_ERROR_IF(lua_topointer(L, -1) != lua_topointer(L, -2),
+                               "Packer registered twice with inconsistent metatable");
+       }
+       lua_pop(L, 1);
+       // then set
+       lua_pushstring(L, regname);
+       lua_rawset(L, -3);
+
+       lua_pop(L, 1);
+}
+
+static bool find_packer(const char *regname, PackerTuple &out)
+{
+       MutexAutoLock autolock(g_packers_lock);
+       auto it = g_packers.find(regname);
+       if (it == g_packers.end())
+               return false;
+       // copy data for thread safety
+       out.first = it->first;
+       out.second = it->second;
+       return true;
+}
+
+static bool find_packer(lua_State *L, int idx, PackerTuple &out)
+{
+#ifndef NDEBUG
+       StackChecker checker(L);
+#endif
+
+       // retrieve metatable of the object
+       if (lua_getmetatable(L, idx) != 1)
+               return false;
+
+       // use our global table to map it to the registry name
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_METATABLE_MAP);
+       assert(lua_istable(L, -1));
+       lua_pushvalue(L, -2);
+       lua_rawget(L, -2);
+       if (lua_isnil(L, -1)) {
+               lua_pop(L, 3);
+               return false;
+       }
+
+       // load the associated data
+       bool found = find_packer(lua_tostring(L, -1), out);
+       FATAL_ERROR_IF(!found, "Inconsistent internal state");
+       lua_pop(L, 3);
+       return true;
+}
+
+//
+// Packing implementation
+//
+
+static VectorRef<PackedInstr> record_object(lua_State *L, int idx, PackedValue &pv,
+               std::unordered_map<const void *, s32> &seen)
+{
+       const void *ptr = lua_topointer(L, idx);
+       assert(ptr);
+       auto found = seen.find(ptr);
+       if (found == seen.end()) {
+               seen[ptr] = pv.i.size();
+               return VectorRef<PackedInstr>();
+       }
+       s32 ref = found->second;
+       assert(ref < (s32)pv.i.size());
+       // reuse the value from first time
+       auto r = emplace(pv, INSTR_PUSHREF);
+       r->ref = ref;
+       pv.i[ref].keep_ref = true;
+       return r;
+}
+
+static VectorRef<PackedInstr> pack_inner(lua_State *L, int idx, int vidx, PackedValue &pv,
+               std::unordered_map<const void *, s32> &seen)
+{
+#ifndef NDEBUG
+       StackChecker checker(L);
+       assert(idx > 0);
+       assert(vidx > 0);
+#endif
+
+       switch (lua_type(L, idx)) {
+               case LUA_TNONE:
+               case LUA_TNIL:
+                       return emplace(pv, LUA_TNIL);
+               case LUA_TBOOLEAN: {
+                       auto r = emplace(pv, LUA_TBOOLEAN);
+                       r->bdata = lua_toboolean(L, idx);
+                       return r;
+               }
+               case LUA_TNUMBER: {
+                       auto r = emplace(pv, LUA_TNUMBER);
+                       r->ndata = lua_tonumber(L, idx);
+                       return r;
+               }
+               case LUA_TSTRING: {
+                       auto r = emplace(pv, LUA_TSTRING);
+                       size_t len;
+                       const char *str = lua_tolstring(L, idx, &len);
+                       assert(str);
+                       r->sdata.assign(str, len);
+                       return r;
+               }
+               case LUA_TTABLE: {
+                       auto r = record_object(L, idx, pv, seen);
+                       if (r)
+                               return r;
+                       break; // execution continues
+               }
+               case LUA_TFUNCTION: {
+                       auto r = record_object(L, idx, pv, seen);
+                       if (r)
+                               return r;
+                       r = emplace(pv, LUA_TFUNCTION);
+                       call_string_dump(L, idx);
+                       size_t len;
+                       const char *str = lua_tolstring(L, -1, &len);
+                       assert(str);
+                       r->sdata.assign(str, len);
+                       lua_pop(L, 1);
+                       return r;
+               }
+               case LUA_TUSERDATA: {
+                       auto r = record_object(L, idx, pv, seen);
+                       if (r)
+                               return r;
+                       PackerTuple ser;
+                       if (!find_packer(L, idx, ser))
+                               throw LuaError("Cannot serialize unsupported userdata");
+                       pv.contains_userdata = true;
+                       r = emplace(pv, LUA_TUSERDATA);
+                       r->sdata = ser.first;
+                       r->ptrdata = ser.second.fin(L, idx);
+                       return r;
+               }
+               default: {
+                       std::string err = "Cannot serialize type ";
+                       err += lua_typename(L, lua_type(L, idx));
+                       throw LuaError(err);
+               }
+       }
+
+       // LUA_TTABLE
+       lua_checkstack(L, 5);
+
+       auto rtable = emplace(pv, LUA_TTABLE);
+       const int vi_table = vidx++;
+
+       lua_pushnil(L);
+       while (lua_next(L, idx) != 0) {
+               // key at -2, value at -1
+               const int ktype = lua_type(L, -2), vtype = lua_type(L, -1);
+               if (ktype == LUA_TNUMBER)
+                       rtable->uidata1++; // narr
+               else
+                       rtable->uidata2++; // nrec
+
+               // check if we can use a shortcut
+               if (can_set_into(ktype, vtype) && suitable_key(L, -2)) {
+                       // push only the value
+                       auto rval = pack_inner(L, absidx(L, -1), vidx, pv, seen);
+                       rval->pop = rval->type != LUA_TTABLE;
+                       // and where to put it:
+                       rval->set_into = vi_table;
+                       if (ktype == LUA_TSTRING)
+                               rval->sdata = lua_tostring(L, -2);
+                       else
+                               rval->sidata1 = lua_tointeger(L, -2);
+                       // pop tables after the fact
+                       if (!rval->pop) {
+                               auto ri1 = emplace(pv, INSTR_POP);
+                               ri1->sidata1 = vidx;
+                       }
+               } else {
+                       // push the key and value
+                       pack_inner(L, absidx(L, -2), vidx, pv, seen);
+                       vidx++;
+                       pack_inner(L, absidx(L, -1), vidx, pv, seen);
+                       vidx++;
+                       // push an instruction to set them
+                       auto ri1 = emplace(pv, INSTR_SETTABLE);
+                       ri1->set_into = vi_table;
+                       ri1->sidata1 = vidx - 2;
+                       ri1->sidata2 = vidx - 1;
+                       ri1->pop = true;
+                       vidx -= 2;
+               }
+
+               lua_pop(L, 1);
+       }
+
+       assert(vidx == vi_table + 1);
+       return rtable;
+}
+
+PackedValue *script_pack(lua_State *L, int idx)
+{
+       if (idx < 0)
+               idx = absidx(L, idx);
+
+       PackedValue pv;
+       std::unordered_map<const void *, s32> seen;
+       pack_inner(L, idx, 1, pv, seen);
+
+       return new PackedValue(std::move(pv));
+}
+
+//
+// Unpacking implementation
+//
+
+void script_unpack(lua_State *L, PackedValue *pv)
+{
+       lua_newtable(L); // table at index top to track ref indices -> objects
+       const int top = lua_gettop(L);
+       int ctr = 0;
+
+       for (size_t packed_idx = 0; packed_idx < pv->i.size(); packed_idx++) {
+               auto &i = pv->i[packed_idx];
+
+               // If leaving values on stack make sure there's space (every 5th iteration)
+               if (!i.pop && (ctr++) >= 5) {
+                       lua_checkstack(L, 5);
+                       ctr = 0;
+               }
+
+               switch (i.type) {
+                       /* Instructions */
+                       case INSTR_SETTABLE:
+                               lua_pushvalue(L, top + i.sidata1); // key
+                               lua_pushvalue(L, top + i.sidata2); // value
+                               lua_rawset(L, top + i.set_into);
+                               if (i.pop) {
+                                       if (i.sidata1 != i.sidata2) {
+                                               // removing moves indices so pop higher index first
+                                               lua_remove(L, top + std::max(i.sidata1, i.sidata2));
+                                               lua_remove(L, top + std::min(i.sidata1, i.sidata2));
+                                       } else {
+                                               lua_remove(L, top + i.sidata1);
+                                       }
+                               }
+                               continue;
+                       case INSTR_POP:
+                               lua_remove(L, top + i.sidata1);
+                               if (i.sidata2 > 0)
+                                       lua_remove(L, top + i.sidata2);
+                               continue;
+                       case INSTR_PUSHREF:
+                               lua_pushinteger(L, i.ref);
+                               lua_rawget(L, top);
+                               break;
+
+                       /* Lua types */
+                       case LUA_TNIL:
+                               lua_pushnil(L);
+                               break;
+                       case LUA_TBOOLEAN:
+                               lua_pushboolean(L, i.bdata);
+                               break;
+                       case LUA_TNUMBER:
+                               lua_pushnumber(L, i.ndata);
+                               break;
+                       case LUA_TSTRING:
+                               lua_pushlstring(L, i.sdata.data(), i.sdata.size());
+                               break;
+                       case LUA_TTABLE:
+                               lua_createtable(L, i.uidata1, i.uidata2);
+                               break;
+                       case LUA_TFUNCTION:
+                               luaL_loadbuffer(L, i.sdata.data(), i.sdata.size(), nullptr);
+                               break;
+                       case LUA_TUSERDATA: {
+                               PackerTuple ser;
+                               sanity_check(find_packer(i.sdata.c_str(), ser));
+                               ser.second.fout(L, i.ptrdata);
+                               i.ptrdata = nullptr; // ownership taken by callback
+                               break;
+                       }
+
+                       default:
+                               assert(0);
+                               break;
+               }
+
+               if (i.keep_ref) {
+                       lua_pushinteger(L, packed_idx);
+                       lua_pushvalue(L, -2);
+                       lua_rawset(L, top);
+               }
+
+               if (i.set_into) {
+                       if (!i.pop)
+                               lua_pushvalue(L, -1);
+                       if (uses_sdata(i.type))
+                               lua_rawseti(L, top + i.set_into, i.sidata1);
+                       else
+                               lua_setfield(L, top + i.set_into, i.sdata.c_str());
+               } else {
+                       if (i.pop)
+                               lua_pop(L, 1);
+               }
+       }
+
+       // as part of the unpacking process we take ownership of all userdata
+       pv->contains_userdata = false;
+       // leave exactly one value on the stack
+       lua_settop(L, top+1);
+       lua_remove(L, top);
+}
+
+//
+// PackedValue
+//
+
+PackedValue::~PackedValue()
+{
+       if (!contains_userdata)
+               return;
+       for (auto &i : this->i) {
+               if (i.type == LUA_TUSERDATA && i.ptrdata) {
+                       PackerTuple ser;
+                       if (find_packer(i.sdata.c_str(), ser)) {
+                               // tell it to deallocate object
+                               ser.second.fout(nullptr, i.ptrdata);
+                       } else {
+                               assert(false);
+                       }
+               }
+       }
+}
+
+//
+// script_dump_packed
+//
+
+#ifndef NDEBUG
+void script_dump_packed(const PackedValue *val)
+{
+       printf("instruction stream: [\n");
+       for (const auto &i : val->i) {
+               printf("\t(");
+               switch (i.type) {
+                       case INSTR_SETTABLE:
+                               printf("SETTABLE(%d, %d)", i.sidata1, i.sidata2);
+                               break;
+                       case INSTR_POP:
+                               printf(i.sidata2 ? "POP(%d, %d)" : "POP(%d)", i.sidata1, i.sidata2);
+                               break;
+                       case INSTR_PUSHREF:
+                               printf("PUSHREF(%d)", i.ref);
+                               break;
+                       case LUA_TNIL:
+                               printf("nil");
+                               break;
+                       case LUA_TBOOLEAN:
+                               printf(i.bdata ? "true" : "false");
+                               break;
+                       case LUA_TNUMBER:
+                               printf("%f", i.ndata);
+                               break;
+                       case LUA_TSTRING:
+                               printf("\"%s\"", i.sdata.c_str());
+                               break;
+                       case LUA_TTABLE:
+                               printf("table(%d, %d)", i.uidata1, i.uidata2);
+                               break;
+                       case LUA_TFUNCTION:
+                               printf("function(%d byte)", i.sdata.size());
+                               break;
+                       case LUA_TUSERDATA:
+                               printf("userdata %s %p", i.sdata.c_str(), i.ptrdata);
+                               break;
+                       default:
+                               printf("!!UNKNOWN!!");
+                               break;
+               }
+               if (i.set_into) {
+                       if (i.type >= 0 && uses_sdata(i.type))
+                               printf(", k=%d, into=%d", i.sidata1, i.set_into);
+                       else if (i.type >= 0)
+                               printf(", k=\"%s\", into=%d", i.sdata.c_str(), i.set_into);
+                       else
+                               printf(", into=%d", i.set_into);
+               }
+               if (i.keep_ref)
+                       printf(", keep_ref");
+               if (i.pop)
+                       printf(", pop");
+               printf(")\n");
+       }
+       printf("]\n");
+}
+#endif
diff --git a/src/script/common/c_packer.h b/src/script/common/c_packer.h
new file mode 100644 (file)
index 0000000..fe072c1
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+Minetest
+Copyright (C) 2022 sfan5 <sfan5@live.de>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include "irrlichttypes.h"
+#include "util/basic_macros.h"
+
+extern "C" {
+#include <lua.h>
+}
+
+/*
+       This file defines an in-memory representation of Lua objects including
+       support for functions and userdata. It it used to move data between Lua
+       states and cannot be used for persistence or network transfer.
+*/
+
+#define INSTR_SETTABLE (-10)
+#define INSTR_POP      (-11)
+#define INSTR_PUSHREF  (-12)
+
+/**
+ * Represents a single instruction that pushes a new value or works with existing ones.
+ */
+struct PackedInstr
+{
+       s16 type; // LUA_T* or INSTR_*
+       u16 set_into; // set into table on stack
+       bool keep_ref; // is referenced later by INSTR_PUSHREF?
+       bool pop; // remove from stack?
+       union {
+               bool bdata; // boolean: value
+               lua_Number ndata; // number: value
+               struct {
+                       u16 uidata1, uidata2; // table: narr, nrec
+               };
+               struct {
+                       /*
+                               SETTABLE: key index, value index
+                               POP: indices to remove
+                               otherwise w/ set_into: numeric key, -
+                       */
+                       s32 sidata1, sidata2;
+               };
+               void *ptrdata; // userdata: implementation defined
+               s32 ref; // PUSHREF: index of referenced instr
+       };
+       /*
+               - string: value
+               - function: buffer
+               - w/ set_into: string key (no null bytes!)
+               - userdata: name in registry
+       */
+       std::string sdata;
+
+       PackedInstr() : type(0), set_into(0), keep_ref(false), pop(false) {}
+};
+
+/**
+ * A packed value can be a primitive like a string or number but also a table
+ * including all of its contents. It is made up of a linear stream of
+ * 'instructions' that build the final value when executed.
+ */
+struct PackedValue
+{
+       std::vector<PackedInstr> i;
+       // Indicates whether there are any userdata pointers that need to be deallocated
+       bool contains_userdata = false;
+
+       PackedValue() = default;
+       ~PackedValue();
+
+       DISABLE_CLASS_COPY(PackedValue)
+
+       ALLOW_CLASS_MOVE(PackedValue)
+};
+
+/*
+ * Packing callback: Turns a Lua value at given index into a void*
+ */
+typedef void *(*PackInFunc)(lua_State *L, int idx);
+/*
+ * Unpacking callback: Turns a void* back into the Lua value (left on top of stack)
+ *
+ * Note that this function must take ownership of the pointer, so make sure
+ * to free or keep the memory.
+ * `L` can be nullptr to indicate that data should just be discarded.
+ */
+typedef void (*PackOutFunc)(lua_State *L, void *ptr);
+/*
+ * Register a packable type with the name of its metatable.
+ *
+ * Even though the callbacks are global this must be called for every Lua state
+ * that supports objects of this type.
+ * This function is thread-safe.
+ */
+void script_register_packer(lua_State *L, const char *regname,
+               PackInFunc fin, PackOutFunc fout);
+
+// Pack a Lua value
+PackedValue *script_pack(lua_State *L, int idx);
+// Unpack a Lua value (left on top of stack)
+// Note that this may modify the PackedValue, reusability is not guaranteed!
+void script_unpack(lua_State *L, PackedValue *val);
+
+// Dump contents of PackedValue to stdout for debugging
+void script_dump_packed(const PackedValue *val);
index dacdcd75a396344ef11aa2959a6e20a43a6e5808..42a794cebcbf49863787c05f3f21b6bfbce5c619 100644 (file)
@@ -21,9 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <cstdlib>
 
 extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
 }
 
 #include "server.h"
@@ -32,6 +32,7 @@ extern "C" {
 #include "filesys.h"
 #include "porting.h"
 #include "common/c_internal.h"
+#include "common/c_packer.h"
 #include "lua_api/l_base.h"
 
 /******************************************************************************/
@@ -76,19 +77,34 @@ void AsyncEngine::initialize(unsigned int numEngines)
 {
        initDone = true;
 
-       for (unsigned int i = 0; i < numEngines; i++) {
-               AsyncWorkerThread *toAdd = new AsyncWorkerThread(this,
-                       std::string("AsyncWorker-") + itos(i));
-               workerThreads.push_back(toAdd);
-               toAdd->start();
+       if (numEngines == 0) {
+               // Leave one core for the main thread and one for whatever else
+               autoscaleMaxWorkers = Thread::getNumberOfProcessors();
+               if (autoscaleMaxWorkers >= 2)
+                       autoscaleMaxWorkers -= 2;
+               infostream << "AsyncEngine: using at most " << autoscaleMaxWorkers
+                       << " threads with automatic scaling" << std::endl;
+
+               addWorkerThread();
+       } else {
+               for (unsigned int i = 0; i < numEngines; i++)
+                       addWorkerThread();
        }
 }
 
+void AsyncEngine::addWorkerThread()
+{
+       AsyncWorkerThread *toAdd = new AsyncWorkerThread(this,
+               std::string("AsyncWorker-") + itos(workerThreads.size()));
+       workerThreads.push_back(toAdd);
+       toAdd->start();
+}
+
 /******************************************************************************/
 u32 AsyncEngine::queueAsyncJob(std::string &&func, std::string &&params,
                const std::string &mod_origin)
 {
-       jobQueueMutex.lock();
+       MutexAutoLock autolock(jobQueueMutex);
        u32 jobId = jobIdCounter++;
 
        jobQueue.emplace_back();
@@ -99,7 +115,23 @@ u32 AsyncEngine::queueAsyncJob(std::string &&func, std::string &&params,
        to_add.mod_origin = mod_origin;
 
        jobQueueCounter.post();
-       jobQueueMutex.unlock();
+       return jobId;
+}
+
+u32 AsyncEngine::queueAsyncJob(std::string &&func, PackedValue *params,
+               const std::string &mod_origin)
+{
+       MutexAutoLock autolock(jobQueueMutex);
+       u32 jobId = jobIdCounter++;
+
+       jobQueue.emplace_back();
+       auto &to_add = jobQueue.back();
+       to_add.id = jobId;
+       to_add.function = std::move(func);
+       to_add.params_ext.reset(params);
+       to_add.mod_origin = mod_origin;
+
+       jobQueueCounter.post();
        return jobId;
 }
 
@@ -131,6 +163,12 @@ void AsyncEngine::putJobResult(LuaJobInfo &&result)
 
 /******************************************************************************/
 void AsyncEngine::step(lua_State *L)
+{
+       stepJobResults(L);
+       stepAutoscale();
+}
+
+void AsyncEngine::stepJobResults(lua_State *L)
 {
        int error_handler = PUSH_ERROR_HANDLER(L);
        lua_getglobal(L, "core");
@@ -148,7 +186,10 @@ void AsyncEngine::step(lua_State *L)
                luaL_checktype(L, -1, LUA_TFUNCTION);
 
                lua_pushinteger(L, j.id);
-               lua_pushlstring(L, j.result.data(), j.result.size());
+               if (j.result_ext)
+                       script_unpack(L, j.result_ext.get());
+               else
+                       lua_pushlstring(L, j.result.data(), j.result.size());
 
                // Call handler
                const char *origin = j.mod_origin.empty() ? nullptr : j.mod_origin.c_str();
@@ -161,12 +202,71 @@ void AsyncEngine::step(lua_State *L)
        lua_pop(L, 2); // Pop core and error handler
 }
 
+void AsyncEngine::stepAutoscale()
+{
+       if (workerThreads.size() >= autoscaleMaxWorkers)
+               return;
+
+       MutexAutoLock autolock(jobQueueMutex);
+
+       // 2) If the timer elapsed, check again
+       if (autoscaleTimer && porting::getTimeMs() >= autoscaleTimer) {
+               autoscaleTimer = 0;
+               // Determine overlap with previous snapshot
+               unsigned int n = 0;
+               for (const auto &it : jobQueue)
+                       n += autoscaleSeenJobs.count(it.id);
+               autoscaleSeenJobs.clear();
+               infostream << "AsyncEngine: " << n << " jobs were still waiting after 1s" << std::endl;
+               // Start this many new threads
+               while (workerThreads.size() < autoscaleMaxWorkers && n > 0) {
+                       addWorkerThread();
+                       n--;
+               }
+               return;
+       }
+
+       // 1) Check if there's anything in the queue
+       if (!autoscaleTimer && !jobQueue.empty()) {
+               // Take a snapshot of all jobs we have seen
+               for (const auto &it : jobQueue)
+                       autoscaleSeenJobs.emplace(it.id);
+               // and set a timer for 1 second
+               autoscaleTimer = porting::getTimeMs() + 1000;
+       }
+}
+
 /******************************************************************************/
-void AsyncEngine::prepareEnvironment(lua_State* L, int top)
+bool AsyncEngine::prepareEnvironment(lua_State* L, int top)
 {
        for (StateInitializer &stateInitializer : stateInitializers) {
                stateInitializer(L, top);
        }
+
+       auto *script = ModApiBase::getScriptApiBase(L);
+       try {
+               script->loadMod(Server::getBuiltinLuaPath() + DIR_DELIM + "init.lua",
+                       BUILTIN_MOD_NAME);
+       } catch (const ModError &e) {
+               errorstream << "Execution of async base environment failed: "
+                       << e.what() << std::endl;
+               FATAL_ERROR("Execution of async base environment failed");
+       }
+
+       // Load per mod stuff
+       if (server) {
+               const auto &list = server->m_async_init_files;
+               try {
+                       for (auto &it : list)
+                               script->loadMod(it.second, it.first);
+               } catch (const ModError &e) {
+                       errorstream << "Failed to load mod script inside async environment." << std::endl;
+                       server->setAsyncFatalError(e.what());
+                       return false;
+               }
+       }
+
+       return true;
 }
 
 /******************************************************************************/
@@ -178,15 +278,25 @@ AsyncWorkerThread::AsyncWorkerThread(AsyncEngine* jobDispatcher,
 {
        lua_State *L = getStack();
 
+       if (jobDispatcher->server) {
+               setGameDef(jobDispatcher->server);
+
+               if (g_settings->getBool("secure.enable_security"))
+                       initializeSecurity();
+       }
+
        // Prepare job lua environment
        lua_getglobal(L, "core");
        int top = lua_gettop(L);
 
        // Push builtin initialization type
-       lua_pushstring(L, "async");
+       lua_pushstring(L, jobDispatcher->server ? "async_game" : "async");
        lua_setglobal(L, "INIT");
 
-       jobDispatcher->prepareEnvironment(L, top);
+       if (!jobDispatcher->prepareEnvironment(L, top)) {
+               // can't throw from here so we're stuck with this
+               isErrored = true;
+       }
 }
 
 /******************************************************************************/
@@ -198,19 +308,20 @@ AsyncWorkerThread::~AsyncWorkerThread()
 /******************************************************************************/
 void* AsyncWorkerThread::run()
 {
-       lua_State *L = getStack();
+       if (isErrored)
+               return nullptr;
 
-       try {
-               loadMod(getServer()->getBuiltinLuaPath() + DIR_DELIM + "init.lua",
-                       BUILTIN_MOD_NAME);
-       } catch (const ModError &e) {
-               errorstream << "Execution of async base environment failed: "
-                       << e.what() << std::endl;
-               FATAL_ERROR("Execution of async base environment failed");
-       }
+       lua_State *L = getStack();
 
        int error_handler = PUSH_ERROR_HANDLER(L);
 
+       auto report_error = [this] (const ModError &e) {
+               if (jobDispatcher->server)
+                       jobDispatcher->server->setAsyncFatalError(e.what());
+               else
+                       errorstream << e.what() << std::endl;
+       };
+
        lua_getglobal(L, "core");
        if (lua_isnil(L, -1)) {
                FATAL_ERROR("Unable to find core within async environment!");
@@ -223,6 +334,8 @@ void* AsyncWorkerThread::run()
                if (!jobDispatcher->getJob(&j) || stopRequested())
                        continue;
 
+               const bool use_ext = !!j.params_ext;
+
                lua_getfield(L, -1, "job_processor");
                if (lua_isnil(L, -1))
                        FATAL_ERROR("Unable to get async job processor!");
@@ -232,7 +345,10 @@ void* AsyncWorkerThread::run()
                        errorstream << "ASYNC WORKER: Unable to deserialize function" << std::endl;
                        lua_pushnil(L);
                }
-               lua_pushlstring(L, j.params.data(), j.params.size());
+               if (use_ext)
+                       script_unpack(L, j.params_ext.get());
+               else
+                       lua_pushlstring(L, j.params.data(), j.params.size());
 
                // Call it
                setOriginDirect(j.mod_origin.empty() ? nullptr : j.mod_origin.c_str());
@@ -241,19 +357,28 @@ void* AsyncWorkerThread::run()
                        try {
                                scriptError(result, "<async>");
                        } catch (const ModError &e) {
-                               errorstream << e.what() << std::endl;
+                               report_error(e);
                        }
                } else {
                        // Fetch result
-                       size_t length;
-                       const char *retval = lua_tolstring(L, -1, &length);
-                       j.result.assign(retval, length);
+                       if (use_ext) {
+                               try {
+                                       j.result_ext.reset(script_pack(L, -1));
+                               } catch (const ModError &e) {
+                                       report_error(e);
+                                       result = LUA_ERRERR;
+                               }
+                       } else {
+                               size_t length;
+                               const char *retval = lua_tolstring(L, -1, &length);
+                               j.result.assign(retval, length);
+                       }
                }
 
                lua_pop(L, 1);  // Pop retval
 
                // Put job result
-               if (!j.result.empty())
+               if (result == 0)
                        jobDispatcher->putJobResult(std::move(j));
        }
 
index 697cb02215334f8848270d446401497c22083467..1e34e40ea55358e2d66f60fd71b1b9df880eb4c0 100644 (file)
@@ -21,11 +21,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <vector>
 #include <deque>
+#include <unordered_set>
+#include <memory>
 
+#include <lua.h>
 #include "threading/semaphore.h"
 #include "threading/thread.h"
-#include "lua.h"
+#include "common/c_packer.h"
 #include "cpp_api/s_base.h"
+#include "cpp_api/s_security.h"
 
 // Forward declarations
 class AsyncEngine;
@@ -42,8 +46,12 @@ struct LuaJobInfo
        std::string function;
        // Parameter to be passed to function (serialized)
        std::string params;
+       // Alternative parameters
+       std::unique_ptr<PackedValue> params_ext;
        // Result of function call (serialized)
        std::string result;
+       // Alternative result
+       std::unique_ptr<PackedValue> result_ext;
        // Name of the mod who invoked this call
        std::string mod_origin;
        // JobID used to identify a job and match it to callback
@@ -51,7 +59,8 @@ struct LuaJobInfo
 };
 
 // Asynchronous working environment
-class AsyncWorkerThread : public Thread, virtual public ScriptApiBase {
+class AsyncWorkerThread : public Thread,
+       virtual public ScriptApiBase, public ScriptApiSecurity {
        friend class AsyncEngine;
 public:
        virtual ~AsyncWorkerThread();
@@ -63,6 +72,7 @@ class AsyncWorkerThread : public Thread, virtual public ScriptApiBase {
 
 private:
        AsyncEngine *jobDispatcher = nullptr;
+       bool isErrored = false;
 };
 
 // Asynchornous thread and job management
@@ -71,6 +81,7 @@ class AsyncEngine {
        typedef void (*StateInitializer)(lua_State *L, int top);
 public:
        AsyncEngine() = default;
+       AsyncEngine(Server *server) : server(server) {};
        ~AsyncEngine();
 
        /**
@@ -81,7 +92,7 @@ class AsyncEngine {
 
        /**
         * Create async engine tasks and lock function registration
-        * @param numEngines Number of async threads to be started
+        * @param numEngines Number of worker threads, 0 for automatic scaling
         */
        void initialize(unsigned int numEngines);
 
@@ -94,9 +105,17 @@ class AsyncEngine {
        u32 queueAsyncJob(std::string &&func, std::string &&params,
                        const std::string &mod_origin = "");
 
+       /**
+        * Queue an async job
+        * @param func Serialized lua function
+        * @param params Serialized parameters (takes ownership!)
+        * @return ID of queued job
+        */
+       u32 queueAsyncJob(std::string &&func, PackedValue *params,
+                       const std::string &mod_origin = "");
+
        /**
         * Engine step to process finished jobs
-        *   the engine step is one way to pass events back, PushFinishedJobs another
         * @param L The Lua stack
         */
        void step(lua_State *L);
@@ -116,19 +135,44 @@ class AsyncEngine {
         */
        void putJobResult(LuaJobInfo &&result);
 
+       /**
+        * Start an additional worker thread
+        */
+       void addWorkerThread();
+
+       /**
+        * Process finished jobs callbacks
+        */
+       void stepJobResults(lua_State *L);
+
+       /**
+        * Handle automatic scaling of worker threads
+        */
+       void stepAutoscale();
+
        /**
         * Initialize environment with current registred functions
         *  this function adds all functions registred by registerFunction to the
         *  passed lua stack
         * @param L Lua stack to initialize
         * @param top Stack position
+        * @return false if a mod error ocurred
         */
-       void prepareEnvironment(lua_State* L, int top);
+       bool prepareEnvironment(lua_State* L, int top);
 
 private:
        // Variable locking the engine against further modification
        bool initDone = false;
 
+       // Maximum number of worker threads for automatic scaling
+       // 0 if disabled
+       unsigned int autoscaleMaxWorkers = 0;
+       u64 autoscaleTimer = 0;
+       std::unordered_set<u32> autoscaleSeenJobs;
+
+       // Only set for the server async environment (duh)
+       Server *server = nullptr;
+
        // Internal store for registred state initializers
        std::vector<StateInitializer> stateInitializers;
 
index 27d730b1d89248936db806acf5331ea4ff28007d..ae4a1677156b88b6d1021a23cdde300f1b70da3f 100644 (file)
@@ -38,6 +38,8 @@ extern "C" {
 #include "lualib.h"
 #if USE_LUAJIT
        #include "luajit.h"
+#else
+       #include "bit.h"
 #endif
 }
 
@@ -89,6 +91,11 @@ ScriptApiBase::ScriptApiBase(ScriptingType type):
        else*/
                luaL_openlibs(m_luastack);
 
+       // Load bit library
+       lua_pushcfunction(m_luastack, luaopen_bit);
+       lua_pushstring(m_luastack, LUA_BITLIBNAME);
+       lua_call(m_luastack, 1, 0);
+
        // Make the ScriptApiBase* accessible to ModApiBase
 #if INDIRECT_SCRIPTAPI_RIDX
        *(void **)(lua_newuserdata(m_luastack, sizeof(void *))) = this;
@@ -115,6 +122,14 @@ ScriptApiBase::ScriptApiBase(ScriptingType type):
        lua_newtable(m_luastack);
        lua_setglobal(m_luastack, "core");
 
+       // vector.metatable is stored in the registry for quick access from C++.
+       lua_newtable(m_luastack);
+       lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE);
+       lua_newtable(m_luastack);
+       lua_rawgeti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE);
+       lua_setfield(m_luastack, -2, "metatable");
+       lua_setglobal(m_luastack, "vector");
+
        if (m_type == ScriptingType::Client)
                lua_pushstring(m_luastack, "/");
        else
index e49745f4e8b6ce860cd0720d873dc375b1e81725..19ae8783b263e4471154a1329b6259dbdfe51731 100644 (file)
@@ -128,6 +128,15 @@ class ScriptApiBase : protected LuaHelper {
        friend class ModApiEnvMod;
        friend class LuaVoxelManip;
 
+       /*
+               Subtle edge case with coroutines: If for whatever reason you have a
+               method in a subclass that's called from existing lua_CFunction
+               (any of the l_*.cpp files) then make it static and take the lua_State*
+               as an argument. This is REQUIRED because getStack() will not return the
+               correct state if called inside coroutines.
+
+               Also note that src/script/common/ is the better place for such helpers.
+       */
        lua_State* getStack()
                { return m_luastack; }
 
index 5d20f547dad6a04ec5c7220795e5d32a071703d3..e54a1361d190cbe727d4fc28f7d727eb4b916b8f 100644 (file)
@@ -399,7 +399,7 @@ bool ScriptApiClient::on_inventory_open(Inventory *inventory)
        lua_getglobal(L, "core");
        lua_getfield(L, -1, "registered_on_inventory_open");
 
-       push_inventory(L, inventory);
+       push_inventory_lists(L, *inventory);
 
        try {
                runCallbacks(1, RUN_CALLBACKS_MODE_OR);
index 746f7013e99d6505770b308378a165d47f1b331f..06337b9e8c16528135226c416443d55aab8e25d9 100644 (file)
@@ -240,7 +240,7 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime,
 //                       tool_capabilities, direction, damage)
 bool ScriptApiEntity::luaentity_Punch(u16 id,
                ServerActiveObject *puncher, float time_from_last_punch,
-               const ToolCapabilities *toolcap, v3f dir, s16 damage)
+               const ToolCapabilities *toolcap, v3f dir, s32 damage)
 {
        SCRIPTAPI_PRECHECKHEADER
 
index b52f6e447a99e522293c737e942ae19bd4fe45cc..7658ae92236c07235a3f74e7d4bbc59673c91339 100644 (file)
@@ -42,7 +42,7 @@ class ScriptApiEntity
                const collisionMoveResult *moveresult);
        bool luaentity_Punch(u16 id,
                        ServerActiveObject *puncher, float time_from_last_punch,
-                       const ToolCapabilities *toolcap, v3f dir, s16 damage);
+                       const ToolCapabilities *toolcap, v3f dir, s32 damage);
        bool luaentity_on_death(u16 id, ServerActiveObject *killer);
        void luaentity_Rightclick(u16 id, ServerActiveObject *clicker);
        void luaentity_on_attach_child(u16 id, ServerActiveObject *child);
index 874c37b6eb53207b061a1d829e51c803cfb471d0..af68f689f9f67552e1e63b4b3bdd91d73f6722d7 100644 (file)
@@ -140,10 +140,10 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
 
                bool simple_catch_up = true;
                getboolfield(L, current_abm, "catch_up", simple_catch_up);
-               
+
                s16 min_y = INT16_MIN;
                getintfield(L, current_abm, "min_y", min_y);
-               
+
                s16 max_y = INT16_MAX;
                getintfield(L, current_abm, "max_y", max_y);
 
index 48dce14f39b37900eaab171fd2dd2dc846b6a860..b1916070e5baec90b5a08181e83c48afda97f4a3 100644 (file)
@@ -59,13 +59,14 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
        return true;
 }
 
-bool ScriptApiItem::item_OnPlace(ItemStack &item,
+bool ScriptApiItem::item_OnPlace(Optional<ItemStack> &ret_item,
                ServerActiveObject *placer, const PointedThing &pointed)
 {
        SCRIPTAPI_PRECHECKHEADER
 
        int error_handler = PUSH_ERROR_HANDLER(L);
 
+       const ItemStack &item = *ret_item;
        // Push callback function on stack
        if (!getItemCallback(item.name.c_str(), "on_place"))
                return false;
@@ -82,22 +83,25 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
        PCALL_RES(lua_pcall(L, 3, 1, error_handler));
        if (!lua_isnil(L, -1)) {
                try {
-                       item = read_item(L, -1, getServer()->idef());
+                       ret_item = read_item(L, -1, getServer()->idef());
                } catch (LuaError &e) {
                        throw WRAP_LUAERROR(e, "item=" + item.name);
                }
+       } else {
+               ret_item = nullopt;
        }
        lua_pop(L, 2);  // Pop item and error handler
        return true;
 }
 
-bool ScriptApiItem::item_OnUse(ItemStack &item,
+bool ScriptApiItem::item_OnUse(Optional<ItemStack> &ret_item,
                ServerActiveObject *user, const PointedThing &pointed)
 {
        SCRIPTAPI_PRECHECKHEADER
 
        int error_handler = PUSH_ERROR_HANDLER(L);
 
+       const ItemStack &item = *ret_item;
        // Push callback function on stack
        if (!getItemCallback(item.name.c_str(), "on_use"))
                return false;
@@ -109,22 +113,25 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
        PCALL_RES(lua_pcall(L, 3, 1, error_handler));
        if(!lua_isnil(L, -1)) {
                try {
-                       item = read_item(L, -1, getServer()->idef());
+                       ret_item = read_item(L, -1, getServer()->idef());
                } catch (LuaError &e) {
                        throw WRAP_LUAERROR(e, "item=" + item.name);
                }
+       } else {
+               ret_item = nullopt;
        }
        lua_pop(L, 2);  // Pop item and error handler
        return true;
 }
 
-bool ScriptApiItem::item_OnSecondaryUse(ItemStack &item,
+bool ScriptApiItem::item_OnSecondaryUse(Optional<ItemStack> &ret_item,
                ServerActiveObject *user, const PointedThing &pointed)
 {
        SCRIPTAPI_PRECHECKHEADER
 
        int error_handler = PUSH_ERROR_HANDLER(L);
 
+       const ItemStack &item = *ret_item;
        if (!getItemCallback(item.name.c_str(), "on_secondary_use"))
                return false;
 
@@ -134,10 +141,12 @@ bool ScriptApiItem::item_OnSecondaryUse(ItemStack &item,
        PCALL_RES(lua_pcall(L, 3, 1, error_handler));
        if (!lua_isnil(L, -1)) {
                try {
-                       item = read_item(L, -1, getServer()->idef());
+                       ret_item = read_item(L, -1, getServer()->idef());
                } catch (LuaError &e) {
                        throw WRAP_LUAERROR(e, "item=" + item.name);
                }
+       } else {
+               ret_item = nullopt;
        }
        lua_pop(L, 2);  // Pop item and error handler
        return true;
index 25a3501f984afb96b2144ece575d59654e55695e..5015d8bd452188bc97de104685473180b8618e9f 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "cpp_api/s_base.h"
 #include "irr_v3d.h"
+#include "util/Optional.h"
 
 struct PointedThing;
 struct ItemStack;
@@ -35,13 +36,20 @@ class ScriptApiItem
 : virtual public ScriptApiBase
 {
 public:
+       /*
+        * Functions with Optional<ItemStack> are for callbacks where Lua may
+        * want to prevent the engine from modifying the inventory after it's done.
+        * This has a longer backstory where on_use may need to empty the player's
+        * inventory without the engine interfering (see issue #6546).
+        */
+
        bool item_OnDrop(ItemStack &item,
                        ServerActiveObject *dropper, v3f pos);
-       bool item_OnPlace(ItemStack &item,
+       bool item_OnPlace(Optional<ItemStack> &item,
                        ServerActiveObject *placer, const PointedThing &pointed);
-       bool item_OnUse(ItemStack &item,
+       bool item_OnUse(Optional<ItemStack> &item,
                        ServerActiveObject *user, const PointedThing &pointed);
-       bool item_OnSecondaryUse(ItemStack &item,
+       bool item_OnSecondaryUse(Optional<ItemStack> &item,
                        ServerActiveObject *user, const PointedThing &pointed);
        bool item_OnCraft(ItemStack &item, ServerActiveObject *user,
                        const InventoryList *old_craft_grid, const InventoryLocation &craft_inv);
index 3f771c838c335afa78adabf931a7a975d5bdc74d..3c6a8445b2da0957c664d4611ccaa0a5ecb0e455 100644 (file)
@@ -53,6 +53,7 @@ class ScriptApiNode
        static struct EnumString es_ContentParamType[];
        static struct EnumString es_ContentParamType2[];
        static struct EnumString es_LiquidType[];
+       static struct EnumString es_LiquidMoveType[];
        static struct EnumString es_NodeBoxType[];
        static struct EnumString es_TextureAlphaMode[];
 };
index d3e6138dc4492ba17b4a09aef9a5a9bc618eb949..22b24f363ab26892e69aa977e722e24409312585 100644 (file)
@@ -60,7 +60,7 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
                float time_from_last_punch,
                const ToolCapabilities *toolcap,
                v3f dir,
-               s16 damage)
+               s32 damage)
 {
        SCRIPTAPI_PRECHECKHEADER
        // Get core.registered_on_punchplayers
index c0f141862106fbb9d78f8069b34cb18c51258203..e866aee464c9b0769ee60451ab78318da70a6150 100644 (file)
@@ -46,7 +46,7 @@ class ScriptApiPlayer : virtual public ScriptApiBase
        void on_cheat(ServerActiveObject *player, const std::string &cheat_type);
        bool on_punchplayer(ServerActiveObject *player, ServerActiveObject *hitter,
                        float time_from_last_punch, const ToolCapabilities *toolcap,
-                       v3f dir, s16 damage);
+                       v3f dir, s32 damage);
        void on_rightclickplayer(ServerActiveObject *player, ServerActiveObject *clicker);
        s32 on_player_hpchange(ServerActiveObject *player, s32 hp_change,
                        const PlayerHPChangeReason &reason);
index bd9c80e15ce32d32cc4dfe570289ee7c0c6b63c3..76509038f3ca303f8e6287f46b14fde4ed08f4db 100644 (file)
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <cerrno>
 #include <string>
+#include <algorithm>
 #include <iostream>
 
 
@@ -97,6 +98,7 @@ void ScriptApiSecurity::initializeSecurity()
                "type",
                "unpack",
                "_VERSION",
+               "vector",
                "xpcall",
        };
        static const char *whitelist_tables[] = {
@@ -106,6 +108,7 @@ void ScriptApiSecurity::initializeSecurity()
                "string",
                "table",
                "math",
+               "bit"
        };
        static const char *io_whitelist[] = {
                "open",
@@ -120,21 +123,17 @@ void ScriptApiSecurity::initializeSecurity()
                "date",
                "difftime",
                "getenv",
-               "setlocale",
                "time",
-               "tmpname",
        };
        static const char *debug_whitelist[] = {
                "gethook",
                "traceback",
                "getinfo",
                "getmetatable",
-               "setupvalue",
                "setmetatable",
                "upvalueid",
                "sethook",
                "debug",
-               "setlocal",
        };
        static const char *package_whitelist[] = {
                "config",
@@ -220,6 +219,7 @@ void ScriptApiSecurity::initializeSecurity()
        // And replace unsafe ones
        SECURE_API(os, remove);
        SECURE_API(os, rename);
+       SECURE_API(os, setlocale);
 
        lua_setglobal(L, "os");
        lua_pop(L, 1);  // Pop old OS
@@ -251,6 +251,15 @@ void ScriptApiSecurity::initializeSecurity()
        lua_pop(L, 1);  // Pop old jit
 #endif
 
+       // Get rid of 'core' in the old globals, we don't want anyone thinking it's
+       // safe or even usable.
+       lua_pushnil(L);
+       lua_setfield(L, old_globals, "core");
+
+       // 'vector' as well.
+       lua_pushnil(L);
+       lua_setfield(L, old_globals, "vector");
+
        lua_pop(L, 1); // Pop globals_backup
 
 
@@ -286,19 +295,21 @@ void ScriptApiSecurity::initializeSecurityClient()
                "rawset",
                "select",
                "setfenv",
-               // getmetatable can be used to escape the sandbox
+               // getmetatable can be used to escape the sandbox <- ???
                "setmetatable",
                "tonumber",
                "tostring",
                "type",
                "unpack",
                "_VERSION",
+               "vector",
                "xpcall",
                // Completely safe libraries
                "coroutine",
                "string",
                "table",
                "math",
+               "bit",
        };
        static const char *os_whitelist[] = {
                "clock",
@@ -307,7 +318,7 @@ void ScriptApiSecurity::initializeSecurityClient()
                "time"
        };
        static const char *debug_whitelist[] = {
-               "getinfo",
+               "getinfo", // used by builtin and unset before mods load
                "traceback"
        };
 #if USE_LUAJIT
@@ -607,6 +618,38 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
        return false;
 }
 
+bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &setting)
+{
+       assert(str_starts_with(setting, "secure."));
+
+       // We have to make sure that this function is being called directly by
+       // a mod, otherwise a malicious mod could override this function and
+       // steal its return value.
+       lua_Debug info;
+
+       // Make sure there's only one item below this function on the stack...
+       if (lua_getstack(L, 2, &info))
+               return false;
+       FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed");
+       FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed");
+
+       // ...and that that item is the main file scope.
+       if (strcmp(info.what, "main") != 0)
+               return false;
+
+       // Mod must be listed in secure.http_mods or secure.trusted_mods
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
+       if (!lua_isstring(L, -1))
+               return false;
+       std::string mod_name = readParam<std::string>(L, -1);
+
+       std::string value = g_settings->get(setting);
+       value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
+       auto mod_list = str_split(value, ',');
+
+       return CONTAINS(mod_list, mod_name);
+}
+
 
 int ScriptApiSecurity::sl_g_dofile(lua_State *L)
 {
@@ -838,3 +881,20 @@ int ScriptApiSecurity::sl_os_remove(lua_State *L)
        return 2;
 }
 
+
+int ScriptApiSecurity::sl_os_setlocale(lua_State *L)
+{
+       const bool cat = lua_gettop(L) > 1;
+       // Don't allow changes
+       if (!lua_isnoneornil(L, 1)) {
+               lua_pushnil(L);
+               return 1;
+       }
+
+       push_original(L, "os", "setlocale");
+       lua_pushnil(L);
+       if (cat)
+               lua_pushvalue(L, 2);
+       lua_call(L, cat ? 2 : 1, 1);
+       return 1;
+}
index 73e763548ea93a668c41499b8d99eed59eedf19c..880ce1638b7765045193605f40606496c4e4781d 100644 (file)
@@ -40,11 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class ScriptApiSecurity : virtual public ScriptApiBase
 {
 public:
-       int getThread(lua_State *L);
-       // creates an empty Lua environment
-       void createEmptyEnv(lua_State *L);
-       // sets the enviroment to the table thats on top of the stack
-       void setLuaEnv(lua_State *L, int thread);
        // Sets up security on the ScriptApi's Lua state
        void initializeSecurity();
        void initializeSecurityClient();
@@ -57,8 +52,17 @@ class ScriptApiSecurity : virtual public ScriptApiBase
        // Checks if mods are allowed to read (and optionally write) to the path
        static bool checkPath(lua_State *L, const char *path, bool write_required,
                        bool *write_allowed=NULL);
+       // Check if mod is whitelisted in the given setting
+       // This additionally checks that the mod's main file scope is executing.
+       static bool checkWhitelisted(lua_State *L, const std::string &setting);
 
 private:
+       int getThread(lua_State *L);
+       // sets the enviroment to the table thats on top of the stack
+       void setLuaEnv(lua_State *L, int thread);
+       // creates an empty Lua environment
+       void createEmptyEnv(lua_State *L);
+
        // Syntax: "sl_" <Library name or 'g' (global)> '_' <Function name>
        // (sl stands for Secure Lua)
 
@@ -75,4 +79,5 @@ class ScriptApiSecurity : virtual public ScriptApiBase
 
        static int sl_os_rename(lua_State *L);
        static int sl_os_remove(lua_State *L);
+       static int sl_os_setlocale(lua_State *L);
 };
index 6ddb2630d45048aa1b64b9e718066497454f283f..c255b0c71cfb6119c81cb8f2e26f971c19ab2ddd 100644 (file)
@@ -198,10 +198,8 @@ std::string ScriptApiServer::formatChatMessage(const std::string &name,
        return ret;
 }
 
-u32 ScriptApiServer::allocateDynamicMediaCallback(int f_idx)
+u32 ScriptApiServer::allocateDynamicMediaCallback(lua_State *L, int f_idx)
 {
-       lua_State *L = getStack();
-
        if (f_idx < 0)
                f_idx = lua_gettop(L) + f_idx + 1;
 
@@ -235,7 +233,7 @@ u32 ScriptApiServer::allocateDynamicMediaCallback(int f_idx)
 
 void ScriptApiServer::freeDynamicMediaCallback(u32 token)
 {
-       lua_State *L = getStack();
+       SCRIPTAPI_PRECHECKHEADER
 
        verbosestream << "freeDynamicMediaCallback(" << token << ")" << std::endl;
 
index c5c3d559606723006e5f1a2b9e9e64c6e2d39fd1..58c8c0e481cec9c97c4f6386fffa18a0b8ce2d22 100644 (file)
@@ -51,7 +51,7 @@ class ScriptApiServer
                const std::string &password);
 
        /* dynamic media handling */
-       u32 allocateDynamicMediaCallback(int f_idx);
+       static u32 allocateDynamicMediaCallback(lua_State *L, int f_idx);
        void freeDynamicMediaCallback(u32 token);
        void on_dynamic_media_added(u32 token, const char *playername);
 
index 45724e604a0d699a6f5d5e8edf5ca8f3542e374c..ec2656c4adeb32f70f2b27a3850a7575ea62748b 100644 (file)
@@ -27,26 +27,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "filesys.h"
 #include <fstream>
 
-static inline void get_data_and_border_flags(lua_State *L, u8 start_i,
-               bool *borders, bool *data)
+static inline void get_data_and_corner_flags(lua_State *L, u8 start_i,
+               bool *corners, bool *data)
 {
        if (!lua_isboolean(L, start_i))
                return;
-       *borders = lua_toboolean(L, start_i);
+       *corners = lua_toboolean(L, start_i);
        if (!lua_isboolean(L, start_i + 1))
                return;
        *data = lua_toboolean(L, start_i + 1);
 }
 
 static void push_area(lua_State *L, const Area *a,
-               bool include_borders, bool include_data)
+               bool include_corners, bool include_data)
 {
-       if (!include_borders && !include_data) {
+       if (!include_corners && !include_data) {
                lua_pushboolean(L, true);
                return;
        }
        lua_newtable(L);
-       if (include_borders) {
+       if (include_corners) {
                push_v3s16(L, a->minedge);
                lua_setfield(L, -2, "min");
                push_v3s16(L, a->maxedge);
@@ -59,13 +59,13 @@ static void push_area(lua_State *L, const Area *a,
 }
 
 static inline void push_areas(lua_State *L, const std::vector<Area *> &areas,
-               bool borders, bool data)
+               bool corners, bool data)
 {
        lua_newtable(L);
        size_t cnt = areas.size();
        for (size_t i = 0; i < cnt; i++) {
                lua_pushnumber(L, areas[i]->id);
-               push_area(L, areas[i], borders, data);
+               push_area(L, areas[i], corners, data);
                lua_settable(L, -3);
        }
 }
@@ -94,7 +94,7 @@ int LuaAreaStore::gc_object(lua_State *L)
        return 0;
 }
 
-// get_area(id, include_borders, include_data)
+// get_area(id, include_corners, include_data)
 int LuaAreaStore::l_get_area(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
@@ -104,9 +104,9 @@ int LuaAreaStore::l_get_area(lua_State *L)
 
        u32 id = luaL_checknumber(L, 2);
 
-       bool include_borders = true;
+       bool include_corners = true;
        bool include_data = false;
-       get_data_and_border_flags(L, 3, &include_borders, &include_data);
+       get_data_and_corner_flags(L, 3, &include_corners, &include_data);
 
        const Area *res;
 
@@ -114,12 +114,12 @@ int LuaAreaStore::l_get_area(lua_State *L)
        if (!res)
                return 0;
 
-       push_area(L, res, include_borders, include_data);
+       push_area(L, res, include_corners, include_data);
 
        return 1;
 }
 
-// get_areas_for_pos(pos, include_borders, include_data)
+// get_areas_for_pos(pos, include_corners, include_data)
 int LuaAreaStore::l_get_areas_for_pos(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
@@ -129,19 +129,19 @@ int LuaAreaStore::l_get_areas_for_pos(lua_State *L)
 
        v3s16 pos = check_v3s16(L, 2);
 
-       bool include_borders = true;
+       bool include_corners = true;
        bool include_data = false;
-       get_data_and_border_flags(L, 3, &include_borders, &include_data);
+       get_data_and_corner_flags(L, 3, &include_corners, &include_data);
 
        std::vector<Area *> res;
 
        ast->getAreasForPos(&res, pos);
-       push_areas(L, res, include_borders, include_data);
+       push_areas(L, res, include_corners, include_data);
 
        return 1;
 }
 
-// get_areas_in_area(edge1, edge2, accept_overlap, include_borders, include_data)
+// get_areas_in_area(corner1, corner2, accept_overlap, include_corners, include_data)
 int LuaAreaStore::l_get_areas_in_area(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
@@ -149,25 +149,26 @@ int LuaAreaStore::l_get_areas_in_area(lua_State *L)
        LuaAreaStore *o = checkobject(L, 1);
        AreaStore *ast = o->as;
 
-       v3s16 minedge = check_v3s16(L, 2);
-       v3s16 maxedge = check_v3s16(L, 3);
+       v3s16 minp = check_v3s16(L, 2);
+       v3s16 maxp = check_v3s16(L, 3);
+       sortBoxVerticies(minp, maxp);
 
-       bool include_borders = true;
+       bool include_corners = true;
        bool include_data = false;
        bool accept_overlap = false;
        if (lua_isboolean(L, 4)) {
                accept_overlap = readParam<bool>(L, 4);
-               get_data_and_border_flags(L, 5, &include_borders, &include_data);
+               get_data_and_corner_flags(L, 5, &include_corners, &include_data);
        }
        std::vector<Area *> res;
 
-       ast->getAreasInArea(&res, minedge, maxedge, accept_overlap);
-       push_areas(L, res, include_borders, include_data);
+       ast->getAreasInArea(&res, minp, maxp, accept_overlap);
+       push_areas(L, res, include_corners, include_data);
 
        return 1;
 }
 
-// insert_area(edge1, edge2, data, id)
+// insert_area(corner1, corner2, data, id)
 int LuaAreaStore::l_insert_area(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
index 1d769c73e9b433b8ad51c02ec5afc7e4a1685158..265c7d3fc6bbe189b497a6ef0432953a1eaf4c0c 100644 (file)
@@ -474,7 +474,7 @@ int ModApiClient::l_get_inventory(lua_State *L)
                inventory = client->getInventory(inventory_location);
                if (! inventory)
                        throw SerializationError(std::string("Attempt to access nonexistant inventory (") + location + ")");
-               push_inventory(L, inventory);
+               push_inventory_lists(L, *inventory);
        } catch (SerializationError &) {
                lua_pushnil(L);
        }
index 18622ee00826faf939986a6a29e32fb233788cbc..137b210be2a8c13876ef5715b8ed4a06cdaa1f84 100644 (file)
@@ -371,8 +371,9 @@ int ModApiCraft::l_clear_craft(lua_State *L)
 int ModApiCraft::l_get_craft_result(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
+       IGameDef *gdef = getGameDef(L);
 
-       int input_i = 1;
+       const int input_i = 1;
        std::string method_s = getstringfield_default(L, input_i, "method", "normal");
        enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method",
                                es_CraftMethod, CRAFT_METHOD_NORMAL);
@@ -382,10 +383,9 @@ int ModApiCraft::l_get_craft_result(lua_State *L)
                width = luaL_checkinteger(L, -1);
        lua_pop(L, 1);
        lua_getfield(L, input_i, "items");
-       std::vector<ItemStack> items = read_items(L, -1,getServer(L));
+       std::vector<ItemStack> items = read_items(L, -1, gdef);
        lua_pop(L, 1); // items
 
-       IGameDef *gdef = getServer(L);
        ICraftDefManager *cdef = gdef->cdef();
        CraftInput input(method, width, items);
        CraftOutput output;
@@ -465,13 +465,13 @@ static void push_craft_recipes(lua_State *L, IGameDef *gdef,
                const std::vector<CraftDefinition*> &recipes,
                const CraftOutput &output)
 {
-       lua_createtable(L, recipes.size(), 0);
-
        if (recipes.empty()) {
                lua_pushnil(L);
                return;
        }
 
+       lua_createtable(L, recipes.size(), 0);
+
        std::vector<CraftDefinition*>::const_iterator it = recipes.begin();
        for (unsigned i = 0; it != recipes.end(); ++it) {
                lua_newtable(L);
@@ -487,10 +487,9 @@ int ModApiCraft::l_get_craft_recipe(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
 
        std::string item = luaL_checkstring(L, 1);
-       Server *server = getServer(L);
+       IGameDef *gdef = getGameDef(L);
        CraftOutput output(item, 0);
-       std::vector<CraftDefinition*> recipes = server->cdef()
-                       ->getCraftRecipes(output, server, 1);
+       auto recipes = gdef->cdef()->getCraftRecipes(output, gdef, 1);
 
        lua_createtable(L, 1, 0);
 
@@ -500,7 +499,7 @@ int ModApiCraft::l_get_craft_recipe(lua_State *L)
                setintfield(L, -1, "width", 0);
                return 1;
        }
-       push_craft_recipe(L, server, recipes[0], output);
+       push_craft_recipe(L, gdef, recipes[0], output);
        return 1;
 }
 
@@ -510,12 +509,11 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
 
        std::string item = luaL_checkstring(L, 1);
-       Server *server = getServer(L);
+       IGameDef *gdef = getGameDef(L);
        CraftOutput output(item, 0);
-       std::vector<CraftDefinition*> recipes = server->cdef()
-                       ->getCraftRecipes(output, server);
+       auto recipes = gdef->cdef()->getCraftRecipes(output, gdef);
 
-       push_craft_recipes(L, server, recipes, output);
+       push_craft_recipes(L, gdef, recipes, output);
        return 1;
 }
 
@@ -527,3 +525,11 @@ void ModApiCraft::Initialize(lua_State *L, int top)
        API_FCT(register_craft);
        API_FCT(clear_craft);
 }
+
+void ModApiCraft::InitializeAsync(lua_State *L, int top)
+{
+       // all read-only functions
+       API_FCT(get_all_craft_recipes);
+       API_FCT(get_craft_recipe);
+       API_FCT(get_craft_result);
+}
index 9002b23efe1b28f926ab616166d24277bef7435f..5234af56f2d2d61b90993dc6733636f2dc6549e5 100644 (file)
@@ -45,4 +45,5 @@ class ModApiCraft : public ModApiBase {
 
 public:
        static void Initialize(lua_State *L, int top);
+       static void InitializeAsync(lua_State *L, int top);
 };
index 876f84d537f443f50ef760a16e59de25bd84c5db..a489d245c431e18b0a4f079b3f5a85283f3ff0c3 100644 (file)
@@ -477,7 +477,7 @@ int ModApiEnvMod::l_place_node(lua_State *L)
                return 1;
        }
        // Create item to place
-       ItemStack item(ndef->get(n).name, 1, 0, idef);
+       Optional<ItemStack> item = ItemStack(ndef->get(n).name, 1, 0, idef);
        // Make pointed position
        PointedThing pointed;
        pointed.type = POINTEDTHING_NODE;
@@ -1038,6 +1038,21 @@ int ModApiEnvMod::l_find_nodes_near_under_air_except(lua_State *L)
        return 2;
 }
 
+static void checkArea(v3s16 &minp, v3s16 &maxp)
+{
+       auto volume = VoxelArea(minp, maxp).getVolume();
+       // Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
+       if (volume > 4096000) {
+               throw LuaError("Area volume exceeds allowed value of 4096000");
+       }
+
+       // Clamp to map range to avoid problems
+#define CLAMP(arg) core::clamp(arg, (s16)-MAX_MAP_GENERATION_LIMIT, (s16)MAX_MAP_GENERATION_LIMIT)
+       minp = v3s16(CLAMP(minp.X), CLAMP(minp.Y), CLAMP(minp.Z));
+       maxp = v3s16(CLAMP(maxp.X), CLAMP(maxp.Y), CLAMP(maxp.Z));
+#undef CLAMP
+}
+
 // find_nodes_in_area(minp, maxp, nodenames, [grouped])
 int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
 {
@@ -1057,13 +1072,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
        }
 #endif
 
-       v3s16 cube = maxp - minp + 1;
-       // Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
-       if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 4096000) {
-               luaL_error(L, "find_nodes_in_area(): area volume"
-                               " exceeds allowed value of 4096000");
-               return 0;
-       }
+       checkArea(minp, maxp);
 
        std::vector<content_t> filter;
        collectNodeIds(L, 3, ndef, filter);
@@ -1168,13 +1177,7 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
        }
 #endif
 
-       v3s16 cube = maxp - minp + 1;
-       // Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
-       if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 4096000) {
-               luaL_error(L, "find_nodes_in_area_under_air(): area volume"
-                               " exceeds allowed value of 4096000");
-               return 0;
-       }
+       checkArea(minp, maxp);
 
        std::vector<content_t> filter;
        collectNodeIds(L, 3, ndef, filter);
@@ -1541,7 +1544,7 @@ int ModApiEnvMod::l_transforming_liquid_add(lua_State *L)
        GET_ENV_PTR;
 
        v3s16 p0 = read_v3s16(L, 1);
-       env->getMap().transforming_liquid_add(p0);
+       env->getServerMap().transforming_liquid_add(p0);
        return 1;
 }
 
index a5ac21e21ffcb2d58954e33430adac5870be51d9..70a8d239881f9c36dff0f3ddb3728d720d4c7c3d 100644 (file)
@@ -114,7 +114,7 @@ class ModApiEnvMod : public ModApiBase {
 
        // get_objects_inside_radius(pos, radius)
        static int l_get_objects_inside_radius(lua_State *L);
-       
+
        // get_objects_in_area(pos, minp, maxp)
        static int l_get_objects_in_area(lua_State *L);
 
index 751ec98376a3dfaf12b9e333ad64003342ed0d0c..5566a8523318c75433d6e90dbd70d33fc5fdf574 100644 (file)
@@ -21,14 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "common/c_converter.h"
 #include "common/c_content.h"
 #include "lua_api/l_http.h"
+#include "cpp_api/s_security.h"
 #include "httpfetch.h"
 #include "settings.h"
 #include "debug.h"
 #include "log.h"
 
-#include <algorithm>
 #include <iomanip>
-#include <cctype>
 
 #define HTTP_API(name) \
        lua_pushstring(L, #name); \
@@ -167,54 +166,22 @@ int ModApiHttp::l_request_http_api(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
 
-       // We have to make sure that this function is being called directly by
-       // a mod, otherwise a malicious mod could override this function and
-       // steal its return value.
-       lua_Debug info;
-
-       // Make sure there's only one item below this function on the stack...
-       if (lua_getstack(L, 2, &info)) {
-               return 0;
-       }
-       FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed");
-       FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed");
-
-       // ...and that that item is the main file scope.
-       if (strcmp(info.what, "main") != 0) {
-               return 0;
-       }
-
-       // Mod must be listed in secure.http_mods or secure.trusted_mods
-       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
-       if (!lua_isstring(L, -1)) {
-               return 0;
-       }
-
-       std::string mod_name = readParam<std::string>(L, -1);
-       std::string http_mods = g_settings->get("secure.http_mods");
-       http_mods.erase(std::remove(http_mods.begin(), http_mods.end(), ' '), http_mods.end());
-       std::vector<std::string> mod_list_http = str_split(http_mods, ',');
-
-       std::string trusted_mods = g_settings->get("secure.trusted_mods");
-       trusted_mods.erase(std::remove(trusted_mods.begin(), trusted_mods.end(), ' '), trusted_mods.end());
-       std::vector<std::string> mod_list_trusted = str_split(trusted_mods, ',');
-
-       mod_list_http.insert(mod_list_http.end(), mod_list_trusted.begin(), mod_list_trusted.end());
-       if (std::find(mod_list_http.begin(), mod_list_http.end(), mod_name) == mod_list_http.end()) {
+       if (!ScriptApiSecurity::checkWhitelisted(L, "secure.http_mods") &&
+                       !ScriptApiSecurity::checkWhitelisted(L, "secure.trusted_mods")) {
                lua_pushnil(L);
                return 1;
        }
 
-       lua_getglobal(L, "core");
-       lua_getfield(L, -1, "http_add_fetch");
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
+       assert(lua_isfunction(L, -1));
 
        lua_newtable(L);
        HTTP_API(fetch_async);
        HTTP_API(fetch_async_get);
 
        // Stack now looks like this:
-       // <core.http_add_fetch> <table with fetch_async, fetch_async_get>
-       // Now call core.http_add_fetch to append .fetch(request, callback) to table
+       // <function> <table with fetch_async, fetch_async_get>
+       // Now call it to append .fetch(request, callback) to table
        lua_call(L, 1, 1);
 
        return 1;
@@ -234,6 +201,22 @@ int ModApiHttp::l_get_http_api(lua_State *L)
 
 #endif
 
+int ModApiHttp::l_set_http_api_lua(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+#if USE_CURL
+       // This is called by builtin to give us a function that will later
+       // populate the http_api table with additional method(s).
+       // We need this because access to the HTTP api is security-relevant and
+       // any mod could just mess with a global variable.
+       luaL_checktype(L, 1, LUA_TFUNCTION);
+       lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_HTTP_API_LUA);
+#endif
+
+       return 0;
+}
+
 void ModApiHttp::Initialize(lua_State *L, int top)
 {
 #if USE_CURL
@@ -247,8 +230,14 @@ void ModApiHttp::Initialize(lua_State *L, int top)
                API_FCT(get_http_api);
        } else {
                API_FCT(request_http_api);
+               API_FCT(set_http_api_lua);
        }
 
+#else
+
+       // Define this function anyway so builtin can call it without checking
+       API_FCT(set_http_api_lua);
+
 #endif
 }
 
index c3a2a52762a2b348f5fc81bd0a25c9eec2673c98..8d084ecd97d35cd42a77f0bcc9b4f8eab04c533d 100644 (file)
@@ -48,6 +48,10 @@ class ModApiHttp : public ModApiBase {
        static int l_get_http_api(lua_State *L);
 #endif
 
+       // set_http_api_lua() [internal]
+       static int l_set_http_api_lua(lua_State *L);
+
+
 public:
        static void Initialize(lua_State *L, int top);
        static void InitializeAsync(lua_State *L, int top);
index 672e535ca56b9a85f3a728e3a5aa7cabc56be7ac..de73ff42ab02675b36abc199549302f1baaef20e 100644 (file)
@@ -69,7 +69,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 // Retrieve Environment pointer as `env` (no map lock)
 #define GET_PLAIN_ENV_PTR_NO_MAP_LOCK            \
-       Environment *env = (Environment *)getEnv(L); \
+       Environment *env = getEnv(L);                \
        if (env == NULL)                             \
                return 0
 
index 0dd4184621dd0d13576180157fd18b10be3bfd83..175047e58b7394ee15b501e4e6d6bb94a681ee84 100644 (file)
@@ -214,11 +214,16 @@ int InvRef::l_get_list(lua_State *L)
        InvRef *ref = checkobject(L, 1);
        const char *listname = luaL_checkstring(L, 2);
        Inventory *inv = getinv(L, ref);
-       if(inv){
-               push_inventory_list(L, inv, listname);
-       } else {
+       if (!inv) {
                lua_pushnil(L);
+               return 1;
        }
+       InventoryList *invlist = inv->getList(listname);
+       if (!invlist) {
+               lua_pushnil(L);
+               return 1;
+       }
+       push_inventory_list(L, *invlist);
        return 1;
 }
 
@@ -242,7 +247,7 @@ int InvRef::l_set_list(lua_State *L)
        return 0;
 }
 
-// get_lists(self) -> list of InventoryLists
+// get_lists(self) -> table that maps listnames to InventoryLists
 int InvRef::l_get_lists(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
@@ -251,15 +256,7 @@ int InvRef::l_get_lists(lua_State *L)
        if (!inv) {
                return 0;
        }
-       std::vector<const InventoryList*> lists = inv->getLists();
-       std::vector<const InventoryList*>::iterator iter = lists.begin();
-       lua_createtable(L, 0, lists.size());
-       for (; iter != lists.end(); iter++) {
-               const char* name = (*iter)->getName().c_str();
-               lua_pushstring(L, name);
-               push_inventory_list(L, inv, name);
-               lua_rawset(L, -3);
-       }
+       push_inventory_lists(L, *inv);
        return 1;
 }
 
@@ -421,19 +418,6 @@ void InvRef::create(lua_State *L, const InventoryLocation &loc)
        luaL_getmetatable(L, className);
        lua_setmetatable(L, -2);
 }
-void InvRef::createPlayer(lua_State *L, RemotePlayer *player)
-{
-       NO_MAP_LOCK_REQUIRED;
-       InventoryLocation loc;
-       loc.setPlayer(player->getName());
-       create(L, loc);
-}
-void InvRef::createNodeMeta(lua_State *L, v3s16 p)
-{
-       InventoryLocation loc;
-       loc.setNodeMeta(p);
-       create(L, loc);
-}
 
 void InvRef::Register(lua_State *L)
 {
index 94f670c9d51d0dce1ce7d157b0e50a7952b62634..6a75bac0f38e4e8a4fcd080dab8462e6ec1294e0 100644 (file)
@@ -111,8 +111,6 @@ class InvRef : public ModApiBase {
        // Creates an InvRef and leaves it on top of stack
        // Not callable from Lua; all references are created on the C side.
        static void create(lua_State *L, const InventoryLocation &loc);
-       static void createPlayer(lua_State *L, RemotePlayer *player);
-       static void createNodeMeta(lua_State *L, v3s16 p);
        static void Register(lua_State *L);
 };
 
index 2ea2bd4f69cd21dea0a747f267c22a10a0548b3b..9220259ff1d6bd59394a9daab87b4755d54115cd 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_internal.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
+#include "common/c_packer.h"
 #include "itemdef.h"
 #include "nodedef.h"
 #include "server.h"
@@ -446,6 +447,7 @@ int LuaItemStack::create_object(lua_State *L)
        lua_setmetatable(L, -2);
        return 1;
 }
+
 // Not callable from Lua
 int LuaItemStack::create(lua_State *L, const ItemStack &item)
 {
@@ -462,6 +464,20 @@ LuaItemStack *LuaItemStack::checkobject(lua_State *L, int narg)
        return *(LuaItemStack **)luaL_checkudata(L, narg, className);
 }
 
+void *LuaItemStack::packIn(lua_State *L, int idx)
+{
+       LuaItemStack *o = checkobject(L, idx);
+       return new ItemStack(o->getItem());
+}
+
+void LuaItemStack::packOut(lua_State *L, void *ptr)
+{
+       ItemStack *stack = reinterpret_cast<ItemStack*>(ptr);
+       if (L)
+               create(L, *stack);
+       delete stack;
+}
+
 void LuaItemStack::Register(lua_State *L)
 {
        lua_newtable(L);
@@ -493,6 +509,8 @@ void LuaItemStack::Register(lua_State *L)
 
        // Can be created from Lua (ItemStack(itemstack or itemstring or table or nil))
        lua_register(L, className, create_object);
+
+       script_register_packer(L, className, packIn, packOut);
 }
 
 const char LuaItemStack::className[] = "ItemStack";
@@ -638,8 +656,8 @@ int ModApiItemMod::l_get_content_id(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        std::string name = luaL_checkstring(L, 1);
 
-       const IItemDefManager *idef = getGameDef(L)->getItemDefManager();
-       const NodeDefManager *ndef = getGameDef(L)->getNodeDefManager();
+       const IItemDefManager *idef = getGameDef(L)->idef();
+       const NodeDefManager *ndef = getGameDef(L)->ndef();
 
        // If this is called at mod load time, NodeDefManager isn't aware of
        // aliases yet, so we need to handle them manually
@@ -664,7 +682,7 @@ int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        content_t c = luaL_checkint(L, 1);
 
-       const NodeDefManager *ndef = getGameDef(L)->getNodeDefManager();
+       const NodeDefManager *ndef = getGameDef(L)->ndef();
        const char *name = ndef->get(c).name.c_str();
 
        lua_pushstring(L, name);
@@ -679,3 +697,10 @@ void ModApiItemMod::Initialize(lua_State *L, int top)
        API_FCT(get_content_id);
        API_FCT(get_name_from_content_id);
 }
+
+void ModApiItemMod::InitializeAsync(lua_State *L, int top)
+{
+       // all read-only functions
+       API_FCT(get_content_id);
+       API_FCT(get_name_from_content_id);
+}
index 16878c101df34a1d598b43d83203ab3d6fd3436b..180975061317225a04929fcc97d271dbbc1b1265 100644 (file)
@@ -141,8 +141,11 @@ class LuaItemStack : public ModApiBase {
        // Not callable from Lua
        static int create(lua_State *L, const ItemStack &item);
        static LuaItemStack* checkobject(lua_State *L, int narg);
-       static void Register(lua_State *L);
 
+       static void *packIn(lua_State *L, int idx);
+       static void packOut(lua_State *L, void *ptr);
+
+       static void Register(lua_State *L);
 };
 
 class ModApiItemMod : public ModApiBase {
@@ -152,6 +155,8 @@ class ModApiItemMod : public ModApiBase {
        static int l_register_alias_raw(lua_State *L);
        static int l_get_content_id(lua_State *L);
        static int l_get_name_from_content_id(lua_State *L);
+
 public:
        static void Initialize(lua_State *L, int top);
+       static void InitializeAsync(lua_State *L, int top);
 };
index 769b3ef2b3bdf3adcefdc9a0e0febe537d2b675c..1da0679d69ea5bfefce9f05fa7d234407615683d 100644 (file)
@@ -196,11 +196,11 @@ int LuaLocalPlayer::l_is_in_liquid_stable(lua_State *L)
        return 1;
 }
 
-int LuaLocalPlayer::l_get_liquid_viscosity(lua_State *L)
+int LuaLocalPlayer::l_get_move_resistance(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
 
-       lua_pushinteger(L, player->liquid_viscosity);
+       lua_pushinteger(L, player->move_resistance);
        return 1;
 }
 
@@ -302,13 +302,15 @@ int LuaLocalPlayer::l_get_control(lua_State *L)
        set("dig",   c.dig);
        set("place", c.place);
        // Player movement in polar coordinates and non-binary speed
-       set("movement_speed",     c.movement_speed);
-       set("movement_direction", c.movement_direction);
+       lua_pushnumber(L, c.movement_speed);
+       lua_setfield(L, -2, "movement_speed");
+       lua_pushnumber(L, c.movement_direction);
+       lua_setfield(L, -2, "movement_direction");
        // Provide direction keys to ensure compatibility
-       set("up",    player->keyPressed & (1 << 0)); // Up, down, left, and right were removed in favor of
-       set("down",  player->keyPressed & (1 << 1)); // analog  direction indicators and are therefore not
-       set("left",  player->keyPressed & (1 << 2)); // available as booleans anymore. The corresponding values
-       set("right", player->keyPressed & (1 << 3)); // can still be read from the keyPressed bits though.
+       set("up",    c.direction_keys & (1 << 0));
+       set("down",  c.direction_keys & (1 << 1));
+       set("left",  c.direction_keys & (1 << 2));
+       set("right", c.direction_keys & (1 << 3));
 
        return 1;
 }
@@ -576,7 +578,6 @@ const luaL_Reg LuaLocalPlayer::methods[] = {
                luamethod(LuaLocalPlayer, is_touching_ground),
                luamethod(LuaLocalPlayer, is_in_liquid),
                luamethod(LuaLocalPlayer, is_in_liquid_stable),
-               luamethod(LuaLocalPlayer, get_liquid_viscosity),
                luamethod(LuaLocalPlayer, is_climbing),
                luamethod(LuaLocalPlayer, swimming_vertical),
                luamethod(LuaLocalPlayer, get_physics_override),
@@ -602,5 +603,7 @@ const luaL_Reg LuaLocalPlayer::methods[] = {
                luamethod(LuaLocalPlayer, get_object),
                luamethod(LuaLocalPlayer, get_hotbar_size),
 
+               luamethod(LuaLocalPlayer, get_move_resistance),
+
                {0, 0}
 };
index bb5a294ca95d4ccf3540d78822fa33b0546fbcb8..458c824e6c00bf88e2a51f49e8cfef3d3ede41c3 100644 (file)
@@ -72,7 +72,6 @@ class LuaLocalPlayer : public ModApiBase
        static int l_is_touching_ground(lua_State *L);
        static int l_is_in_liquid(lua_State *L);
        static int l_is_in_liquid_stable(lua_State *L);
-       static int l_get_liquid_viscosity(lua_State *L);
        static int l_is_climbing(lua_State *L);
        static int l_swimming_vertical(lua_State *L);
 
@@ -121,6 +120,8 @@ class LuaLocalPlayer : public ModApiBase
        // hud_get(self, id)
        static int l_hud_get(lua_State *L);
 
+       static int l_get_move_resistance(lua_State *L);
+
        // get_object(self)
        static int l_get_object(lua_State *L);
 
index 8eb0e252a11260f153338405e158f83eaa773b5d..2b46a4d51b85041f7eed302d6fe58a7a92f01b40 100644 (file)
@@ -323,9 +323,9 @@ int ModApiMainMenu::l_get_games(lua_State *L)
                lua_newtable(L);
                int table2 = lua_gettop(L);
                int internal_index = 1;
-               for (const std::string &addon_mods_path : game.addon_mods_paths) {
+               for (const auto &addon_mods_path : game.addon_mods_paths) {
                        lua_pushnumber(L, internal_index);
-                       lua_pushstring(L, addon_mods_path.c_str());
+                       lua_pushstring(L, addon_mods_path.second.c_str());
                        lua_settable(L,   table2);
                        internal_index++;
                }
@@ -414,25 +414,53 @@ int ModApiMainMenu::l_create_world(lua_State *L)
        const char *name        = luaL_checkstring(L, 1);
        int gameidx                     = luaL_checkinteger(L,2) -1;
 
+       StringMap use_settings;
+       luaL_checktype(L, 3, LUA_TTABLE);
+       lua_pushnil(L);
+       while (lua_next(L, 3) != 0) {
+               // key at index -2 and value at index -1
+               use_settings[luaL_checkstring(L, -2)] = luaL_checkstring(L, -1);
+               lua_pop(L, 1);
+       }
+       lua_pop(L, 1);
+
        std::string path = porting::path_user + DIR_DELIM
                        "worlds" + DIR_DELIM
                        + sanitizeDirName(name, "world_");
 
        std::vector<SubgameSpec> games = getAvailableGames();
+       if (gameidx < 0 || gameidx >= (int) games.size()) {
+               lua_pushstring(L, "Invalid game index");
+               return 1;
+       }
 
-       if ((gameidx >= 0) &&
-                       (gameidx < (int) games.size())) {
+       // Set the settings for world creation
+       // this is a bad hack but the best we have right now..
+       StringMap backup;
+       for (auto it : use_settings) {
+               if (g_settings->existsLocal(it.first))
+                       backup[it.first] = g_settings->get(it.first);
+               g_settings->set(it.first, it.second);
+       }
 
-               // Create world if it doesn't exist
-               try {
-                       loadGameConfAndInitWorld(path, name, games[gameidx], true);
-                       lua_pushnil(L);
-               } catch (const BaseException &e) {
-                       lua_pushstring(L, (std::string("Failed to initialize world: ") + e.what()).c_str());
-               }
-       } else {
-               lua_pushstring(L, "Invalid game index");
+       // Create world if it doesn't exist
+       try {
+               loadGameConfAndInitWorld(path, name, games[gameidx], true);
+               lua_pushnil(L);
+       } catch (const BaseException &e) {
+               auto err = std::string("Failed to initialize world: ") + e.what();
+               lua_pushstring(L, err.c_str());
+       }
+
+       // Restore previous settings
+       for (auto it : use_settings) {
+               auto it2 = backup.find(it.first);
+               if (it2 == backup.end())
+                       g_settings->remove(it.first); // wasn't set before
+               else
+                       g_settings->set(it.first, it2->second); // was set before
        }
+
        return 1;
 }
 
@@ -502,6 +530,21 @@ int ModApiMainMenu::l_get_modpath(lua_State *L)
        return 1;
 }
 
+/******************************************************************************/
+int ModApiMainMenu::l_get_modpaths(lua_State *L)
+{
+       lua_newtable(L);
+
+       ModApiMainMenu::l_get_modpath(L);
+       lua_setfield(L, -2, "mods");
+
+       for (const std::string &component : getEnvModPaths()) {
+               lua_pushstring(L, component.c_str());
+               lua_setfield(L, -2, fs::AbsolutePath(component).c_str());
+       }
+       return 1;
+}
+
 /******************************************************************************/
 int ModApiMainMenu::l_get_clientmodpath(lua_State *L)
 {
@@ -548,7 +591,10 @@ int ModApiMainMenu::l_get_cache_path(lua_State *L)
 /******************************************************************************/
 int ModApiMainMenu::l_get_temp_path(lua_State *L)
 {
-       lua_pushstring(L, fs::TempPath().c_str());
+       if (lua_isnoneornil(L, 1) || !lua_toboolean(L, 1))
+               lua_pushstring(L, fs::TempPath().c_str());
+       else
+               lua_pushstring(L, fs::CreateTempFile().c_str());
        return 1;
 }
 
@@ -588,26 +634,24 @@ int ModApiMainMenu::l_copy_dir(lua_State *L)
        const char *destination = luaL_checkstring(L, 2);
 
        bool keep_source = true;
+       if (!lua_isnoneornil(L, 3))
+               keep_source = readParam<bool>(L, 3);
 
-       if ((!lua_isnone(L,3)) &&
-                       (!lua_isnil(L,3))) {
-               keep_source = readParam<bool>(L,3);
-       }
-
-       std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
-       std::string absolute_source = fs::RemoveRelativePathComponents(source);
+       std::string abs_destination = fs::RemoveRelativePathComponents(destination);
+       std::string abs_source = fs::RemoveRelativePathComponents(source);
 
-       if ((ModApiMainMenu::mayModifyPath(absolute_destination))) {
-               bool retval = fs::CopyDir(absolute_source,absolute_destination);
-
-               if (retval && (!keep_source)) {
-
-                       retval &= fs::RecursiveDelete(absolute_source);
-               }
-               lua_pushboolean(L,retval);
+       if (!ModApiMainMenu::mayModifyPath(abs_destination) ||
+               (!keep_source && !ModApiMainMenu::mayModifyPath(abs_source))) {
+               lua_pushboolean(L, false);
                return 1;
        }
-       lua_pushboolean(L,false);
+
+       bool retval;
+       if (keep_source)
+               retval = fs::CopyDir(abs_source, abs_destination);
+       else
+               retval = fs::MoveDir(abs_source, abs_destination);
+       lua_pushboolean(L, retval);
        return 1;
 }
 
@@ -629,9 +673,9 @@ int ModApiMainMenu::l_extract_zip(lua_State *L)
        std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
 
        if (ModApiMainMenu::mayModifyPath(absolute_destination)) {
-               auto rendering_engine = getGuiEngine(L)->m_rendering_engine;
-               fs::CreateAllDirs(absolute_destination);
-               lua_pushboolean(L, fs::extractZipFile(rendering_engine->get_filesystem(), zipfile, destination));
+               auto fs = RenderingEngine::get_raw_device()->getFileSystem();
+               bool ok = fs::extractZipFile(fs, zipfile, destination);
+               lua_pushboolean(L, ok);
                return 1;
        }
 
@@ -759,8 +803,9 @@ int ModApiMainMenu::l_get_video_drivers(lua_State *L)
 /******************************************************************************/
 int ModApiMainMenu::l_gettext(lua_State *L)
 {
-       std::string text = strgettext(std::string(luaL_checkstring(L, 1)));
-       lua_pushstring(L, text.c_str());
+       const char *srctext = luaL_checkstring(L, 1);
+       const char *text = *srctext ? gettext(srctext) : "";
+       lua_pushstring(L, text);
 
        return 1;
 }
@@ -860,6 +905,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
        API_FCT(get_mapgen_names);
        API_FCT(get_user_path);
        API_FCT(get_modpath);
+       API_FCT(get_modpaths);
        API_FCT(get_clientmodpath);
        API_FCT(get_gamepath);
        API_FCT(get_texturepath);
@@ -893,6 +939,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
        API_FCT(get_mapgen_names);
        API_FCT(get_user_path);
        API_FCT(get_modpath);
+       API_FCT(get_modpaths);
        API_FCT(get_clientmodpath);
        API_FCT(get_gamepath);
        API_FCT(get_texturepath);
@@ -903,10 +950,10 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
        API_FCT(delete_dir);
        API_FCT(copy_dir);
        API_FCT(is_dir);
-       //API_FCT(extract_zip); //TODO remove dependency to GuiEngine
+       API_FCT(extract_zip);
        API_FCT(may_modify_path);
        API_FCT(download_file);
        API_FCT(get_min_supp_proto);
        API_FCT(get_max_supp_proto);
-       //API_FCT(gettext); (gettext lib isn't threadsafe)
+       API_FCT(gettext);
 }
index ec2d20da2630ed59c44217335f62337b745d74f9..781185425196b7f9931f0c4d3f46a10d2de739e4 100644 (file)
@@ -112,6 +112,8 @@ class ModApiMainMenu: public ModApiBase
 
        static int l_get_modpath(lua_State *L);
 
+       static int l_get_modpaths(lua_State *L);
+
        static int l_get_clientmodpath(lua_State *L);
 
        static int l_get_gamepath(lua_State *L);
index 21002e6a70734bb0c674cde9596e79263da5f9bd..d00cb4daa7c4d53348c4abe0f22f3361d2254df0 100644 (file)
@@ -82,9 +82,10 @@ int MetaDataRef::l_get(lua_State *L)
        std::string str;
        if (meta->getStringToRef(name, str)) {
                lua_pushlstring(L, str.c_str(), str.size());
-               return 1;
+       } else {
+               lua_pushnil(L);
        }
-       return 0;
+       return 1;
 }
 
 // get_string(self, name)
index 60d14f8f2029b26e121bb27a71217a80bc2300e0..1d052685e4fbc5dbae4ef632933448d5cd0bf117 100644 (file)
@@ -89,7 +89,10 @@ int NodeMetaRef::l_get_inventory(lua_State *L)
 
        NodeMetaRef *ref = checkobject(L, 1);
        ref->getmeta(true);  // try to ensure the metadata exists
-       InvRef::createNodeMeta(L, ref->m_p);
+
+       InventoryLocation loc;
+       loc.setNodeMeta(ref->m_p);
+       InvRef::create(L, loc);
        return 1;
 }
 
@@ -124,18 +127,14 @@ void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta)
        // fields
        MetaDataRef::handleToTable(L, _meta);
 
-       NodeMetadata *meta = (NodeMetadata*) _meta;
+       NodeMetadata *meta = (NodeMetadata *) _meta;
 
        // inventory
-       lua_newtable(L);
        Inventory *inv = meta->getInventory();
        if (inv) {
-               std::vector<const InventoryList *> lists = inv->getLists();
-               for(std::vector<const InventoryList *>::const_iterator
-                               i = lists.begin(); i != lists.end(); ++i) {
-                       push_inventory_list(L, inv, (*i)->getName().c_str());
-                       lua_setfield(L, -2, (*i)->getName().c_str());
-               }
+               push_inventory_lists(L, *inv);
+       } else {
+               lua_newtable(L);
        }
        lua_setfield(L, -2, "inventory");
 }
index f43ba837a3d6b2bc17cd5d3ce1bd22f46d2721be..5561eaebf90c01e074d7f19bb794809c1f2ad399 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_internal.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
+#include "common/c_packer.h"
 #include "log.h"
 #include "porting.h"
 #include "util/numeric.h"
@@ -30,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
   LuaPerlinNoise
 */
 
-LuaPerlinNoise::LuaPerlinNoise(NoiseParams *params) :
+LuaPerlinNoise::LuaPerlinNoise(const NoiseParams *params) :
        np(*params)
 {
 }
@@ -101,6 +102,25 @@ LuaPerlinNoise *LuaPerlinNoise::checkobject(lua_State *L, int narg)
 }
 
 
+void *LuaPerlinNoise::packIn(lua_State *L, int idx)
+{
+       LuaPerlinNoise *o = checkobject(L, idx);
+       return new NoiseParams(o->np);
+}
+
+void LuaPerlinNoise::packOut(lua_State *L, void *ptr)
+{
+       NoiseParams *np = reinterpret_cast<NoiseParams*>(ptr);
+       if (L) {
+               LuaPerlinNoise *o = new LuaPerlinNoise(np);
+               *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+               luaL_getmetatable(L, className);
+               lua_setmetatable(L, -2);
+       }
+       delete np;
+}
+
+
 void LuaPerlinNoise::Register(lua_State *L)
 {
        lua_newtable(L);
@@ -126,6 +146,8 @@ void LuaPerlinNoise::Register(lua_State *L)
        lua_pop(L, 1);
 
        lua_register(L, className, create_object);
+
+       script_register_packer(L, className, packIn, packOut);
 }
 
 
@@ -141,12 +163,10 @@ luaL_Reg LuaPerlinNoise::methods[] = {
   LuaPerlinNoiseMap
 */
 
-LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, s32 seed, v3s16 size)
+LuaPerlinNoiseMap::LuaPerlinNoiseMap(const NoiseParams *np, s32 seed, v3s16 size)
 {
-       m_is3d = size.Z > 1;
-       np = *params;
        try {
-               noise = new Noise(&np, seed, size.X, size.Y, size.Z);
+               noise = new Noise(np, seed, size.X, size.Y, size.Z);
        } catch (InvalidNoiseParamsException &e) {
                throw LuaError(e.what());
        }
@@ -217,7 +237,7 @@ int LuaPerlinNoiseMap::l_get_3d_map(lua_State *L)
        LuaPerlinNoiseMap *o = checkobject(L, 1);
        v3f p = check_v3f(L, 2);
 
-       if (!o->m_is3d)
+       if (!o->is3D())
                return 0;
 
        Noise *n = o->noise;
@@ -248,7 +268,7 @@ int LuaPerlinNoiseMap::l_get_3d_map_flat(lua_State *L)
        v3f p                = check_v3f(L, 2);
        bool use_buffer      = lua_istable(L, 3);
 
-       if (!o->m_is3d)
+       if (!o->is3D())
                return 0;
 
        Noise *n = o->noise;
@@ -289,7 +309,7 @@ int LuaPerlinNoiseMap::l_calc_3d_map(lua_State *L)
        LuaPerlinNoiseMap *o = checkobject(L, 1);
        v3f p                = check_v3f(L, 2);
 
-       if (!o->m_is3d)
+       if (!o->is3D())
                return 0;
 
        Noise *n = o->noise;
@@ -359,6 +379,35 @@ LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
 }
 
 
+struct NoiseMapParams {
+       NoiseParams np;
+       s32 seed;
+       v3s16 size;
+};
+
+void *LuaPerlinNoiseMap::packIn(lua_State *L, int idx)
+{
+       LuaPerlinNoiseMap *o = checkobject(L, idx);
+       NoiseMapParams *ret = new NoiseMapParams();
+       ret->np = o->noise->np;
+       ret->seed = o->noise->seed;
+       ret->size = v3s16(o->noise->sx, o->noise->sy, o->noise->sz);
+       return ret;
+}
+
+void LuaPerlinNoiseMap::packOut(lua_State *L, void *ptr)
+{
+       NoiseMapParams *p = reinterpret_cast<NoiseMapParams*>(ptr);
+       if (L) {
+               LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(&p->np, p->seed, p->size);
+               *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+               luaL_getmetatable(L, className);
+               lua_setmetatable(L, -2);
+       }
+       delete p;
+}
+
+
 void LuaPerlinNoiseMap::Register(lua_State *L)
 {
        lua_newtable(L);
@@ -384,6 +433,8 @@ void LuaPerlinNoiseMap::Register(lua_State *L)
        lua_pop(L, 1);
 
        lua_register(L, className, create_object);
+
+       script_register_packer(L, className, packIn, packOut);
 }
 
 
index 9f50dfd3fee7d8b3559c563a9606a1aacd7de76b..5d34a479bdd86efedacba60676a473ac6fd88597 100644 (file)
@@ -30,6 +30,7 @@ class LuaPerlinNoise : public ModApiBase
 {
 private:
        NoiseParams np;
+
        static const char className[];
        static luaL_Reg methods[];
 
@@ -42,7 +43,7 @@ class LuaPerlinNoise : public ModApiBase
        static int l_get_3d(lua_State *L);
 
 public:
-       LuaPerlinNoise(NoiseParams *params);
+       LuaPerlinNoise(const NoiseParams *params);
        ~LuaPerlinNoise() = default;
 
        // LuaPerlinNoise(seed, octaves, persistence, scale)
@@ -51,6 +52,9 @@ class LuaPerlinNoise : public ModApiBase
 
        static LuaPerlinNoise *checkobject(lua_State *L, int narg);
 
+       static void *packIn(lua_State *L, int idx);
+       static void packOut(lua_State *L, void *ptr);
+
        static void Register(lua_State *L);
 };
 
@@ -59,9 +63,8 @@ class LuaPerlinNoise : public ModApiBase
 */
 class LuaPerlinNoiseMap : public ModApiBase
 {
-       NoiseParams np;
        Noise *noise;
-       bool m_is3d;
+
        static const char className[];
        static luaL_Reg methods[];
 
@@ -80,16 +83,20 @@ class LuaPerlinNoiseMap : public ModApiBase
        static int l_get_map_slice(lua_State *L);
 
 public:
-       LuaPerlinNoiseMap(NoiseParams *np, s32 seed, v3s16 size);
-
+       LuaPerlinNoiseMap(const NoiseParams *np, s32 seed, v3s16 size);
        ~LuaPerlinNoiseMap();
 
+       inline bool is3D() const { return noise->sz > 1; }
+
        // LuaPerlinNoiseMap(np, size)
        // Creates an LuaPerlinNoiseMap and leaves it on top of stack
        static int create_object(lua_State *L);
 
        static LuaPerlinNoiseMap *checkobject(lua_State *L, int narg);
 
+       static void *packIn(lua_State *L, int idx);
+       static void packOut(lua_State *L, void *ptr);
+
        static void Register(lua_State *L);
 };
 
index b7185f7ec5a98f711cfdd2ea0473e28f50258d17..39b19364eb91157d0fa9f7d90f2b90bce923b9ff 100644 (file)
@@ -174,7 +174,7 @@ int ObjectRef::l_punch(lua_State *L)
        v3f dir = readParam<v3f>(L, 5, sao->getBasePosition() - puncher->getBasePosition());
        dir.normalize();
 
-       u16 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch);
+       u32 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch);
        lua_pushnumber(L, wear);
 
        return 1;
@@ -420,8 +420,7 @@ int ObjectRef::l_set_local_animation(lua_State *L)
        float frame_speed = readParam<float>(L, 6, 30.0f);
 
        getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_local_animation(self)
@@ -464,8 +463,7 @@ int ObjectRef::l_set_eye_offset(lua_State *L)
        offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
 
        getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_eye_offset(self)
@@ -737,8 +735,7 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L)
 
        prop->validate();
        sao->notifyObjectPropertiesModified();
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_nametag_attributes(self)
@@ -1116,7 +1113,7 @@ int ObjectRef::l_set_look_vertical(lua_State *L)
        float pitch = readParam<float>(L, 2) * core::RADTODEG;
 
        playersao->setLookPitchAndSend(pitch);
-       return 1;
+       return 0;
 }
 
 // set_look_horizontal(self, radians)
@@ -1131,7 +1128,7 @@ int ObjectRef::l_set_look_horizontal(lua_State *L)
        float yaw = readParam<float>(L, 2) * core::RADTODEG;
 
        playersao->setPlayerYawAndSend(yaw);
-       return 1;
+       return 0;
 }
 
 // DEPRECATED
@@ -1151,7 +1148,7 @@ int ObjectRef::l_set_look_pitch(lua_State *L)
        float pitch = readParam<float>(L, 2) * core::RADTODEG;
 
        playersao->setLookPitchAndSend(pitch);
-       return 1;
+       return 0;
 }
 
 // DEPRECATED
@@ -1171,7 +1168,7 @@ int ObjectRef::l_set_look_yaw(lua_State *L)
        float yaw = readParam<float>(L, 2) * core::RADTODEG;
 
        playersao->setPlayerYawAndSend(yaw);
-       return 1;
+       return 0;
 }
 
 // set_fov(self, degrees, is_multiplier, transition_time)
@@ -1310,8 +1307,7 @@ int ObjectRef::l_set_inventory_formspec(lua_State *L)
 
        player->inventory_formspec = formspec;
        getServer(L)->reportInventoryFormspecModified(player->getName());
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_inventory_formspec(self) -> formspec
@@ -1342,8 +1338,7 @@ int ObjectRef::l_set_formspec_prepend(lua_State *L)
 
        player->formspec_prepend = formspec;
        getServer(L)->reportFormspecPrependModified(player->getName());
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_formspec_prepend(self)
@@ -1367,20 +1362,19 @@ int ObjectRef::l_get_player_control(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        ObjectRef *ref = checkobject(L, 1);
        RemotePlayer *player = getplayer(ref);
-       if (player == nullptr) {
-               lua_pushlstring(L, "", 0);
-               return 1;
-       }
 
-       const PlayerControl &control = player->getPlayerControl();
        lua_newtable(L);
-       lua_pushboolean(L, player->keyPressed & (1 << 0));
+       if (player == nullptr)
+               return 1;
+       
+       const PlayerControl &control = player->getPlayerControl();
+       lua_pushboolean(L, control.direction_keys & (1 << 0));
        lua_setfield(L, -2, "up");
-       lua_pushboolean(L, player->keyPressed & (1 << 1));
+       lua_pushboolean(L, control.direction_keys & (1 << 1));
        lua_setfield(L, -2, "down");
-       lua_pushboolean(L, player->keyPressed & (1 << 2));
+       lua_pushboolean(L, control.direction_keys & (1 << 2));
        lua_setfield(L, -2, "left");
-       lua_pushboolean(L, player->keyPressed & (1 << 3));
+       lua_pushboolean(L, control.direction_keys & (1 << 3));
        lua_setfield(L, -2, "right");
        lua_pushboolean(L, control.jump);
        lua_setfield(L, -2, "jump");
@@ -1409,11 +1403,25 @@ int ObjectRef::l_get_player_control_bits(lua_State *L)
        ObjectRef *ref = checkobject(L, 1);
        RemotePlayer *player = getplayer(ref);
        if (player == nullptr) {
-               lua_pushlstring(L, "", 0);
+               lua_pushinteger(L, 0);
                return 1;
        }
 
-       lua_pushnumber(L, player->keyPressed);
+       const auto &c = player->getPlayerControl();
+
+       // This is very close to PlayerControl::getKeysPressed() but duplicated
+       // here so the encoding in the API is not inadvertedly changed.
+       u32 keypress_bits =
+               c.direction_keys |
+               ( (u32)(c.jump  & 1) << 4) |
+               ( (u32)(c.aux1  & 1) << 5) |
+               ( (u32)(c.sneak & 1) << 6) |
+               ( (u32)(c.dig   & 1) << 7) |
+               ( (u32)(c.place & 1) << 8) |
+               ( (u32)(c.zoom  & 1) << 9)
+       ;
+
+       lua_pushinteger(L, keypress_bits);
        return 1;
 }
 
@@ -1590,8 +1598,7 @@ int ObjectRef::l_hud_set_flags(lua_State *L)
        if (!getServer(L)->hudSetFlags(player, flags, mask))
                return 0;
 
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // hud_get_flags(self)
@@ -1604,20 +1611,11 @@ int ObjectRef::l_hud_get_flags(lua_State *L)
                return 0;
 
        lua_newtable(L);
-       lua_pushboolean(L, player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE);
-       lua_setfield(L, -2, "hotbar");
-       lua_pushboolean(L, player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE);
-       lua_setfield(L, -2, "healthbar");
-       lua_pushboolean(L, player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE);
-       lua_setfield(L, -2, "crosshair");
-       lua_pushboolean(L, player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE);
-       lua_setfield(L, -2, "wielditem");
-       lua_pushboolean(L, player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE);
-       lua_setfield(L, -2, "breathbar");
-       lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE);
-       lua_setfield(L, -2, "minimap");
-       lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE);
-       lua_setfield(L, -2, "minimap_radar");
+       const EnumString *esp = es_HudBuiltinElement;
+       for (int i = 0; esp[i].str; i++) {
+               lua_pushboolean(L, (player->hud_flags & esp[i].num) != 0);
+               lua_setfield(L, -2, esp[i].str);
+       }
        return 1;
 }
 
@@ -1722,9 +1720,11 @@ int ObjectRef::l_set_sky(lua_State *L)
                return 0;
 
        SkyboxParams sky_params = player->getSkyParams();
-       bool is_colorspec = is_color_table(L, 2);
 
-       if (lua_istable(L, 2) && !is_colorspec) {
+       // reset if empty
+       if (lua_isnoneornil(L, 2) && lua_isnone(L, 3)) {
+               sky_params = SkyboxDefaults::getSkyDefaults();
+       } else if (lua_istable(L, 2) && !is_color_table(L, 2)) {
                lua_getfield(L, 2, "base_color");
                if (!lua_isnil(L, -1))
                        read_color(L, -1, &sky_params.bgcolor);
@@ -1748,17 +1748,11 @@ int ObjectRef::l_set_sky(lua_State *L)
                }
                lua_pop(L, 1);
 
-               /*
-               We want to avoid crashes, so we're checking even if we're not using them.
-               However, we want to ensure that the skybox can be set to nil when
-               using "regular" or "plain" skybox modes as textures aren't needed.
-               */
-
-               if (sky_params.textures.size() != 6 && sky_params.textures.size() > 0)
+               // Validate that we either have six or zero textures
+               if (sky_params.textures.size() != 6 && !sky_params.textures.empty())
                        throw LuaError("Skybox expects 6 textures!");
 
-               sky_params.clouds = getboolfield_default(L, 2,
-                       "clouds", sky_params.clouds);
+               sky_params.clouds = getboolfield_default(L, 2, "clouds", sky_params.clouds);
 
                lua_getfield(L, 2, "sky_color");
                if (lua_istable(L, -1)) {
@@ -1806,7 +1800,7 @@ int ObjectRef::l_set_sky(lua_State *L)
                                sky_params.fog_tint_type = luaL_checkstring(L, -1);
                        lua_pop(L, 1);
 
-                       // Because we need to leave the "sky_color" table.
+                       // pop "sky_color" table
                        lua_pop(L, 1);
                }
        } else {
@@ -1842,11 +1836,8 @@ int ObjectRef::l_set_sky(lua_State *L)
                if (lua_istable(L, 4)) {
                        lua_pushnil(L);
                        while (lua_next(L, 4) != 0) {
-                       // Key at index -2, and value at index -1
-                               if (lua_isstring(L, -1))
-                                       sky_params.textures.emplace_back(readParam<std::string>(L, -1));
-                               else
-                                       sky_params.textures.emplace_back("");
+                               // Key at index -2, and value at index -1
+                               sky_params.textures.emplace_back(readParam<std::string>(L, -1));
                                // Remove the value, keep the key for the next iteration
                                lua_pop(L, 1);
                        }
@@ -1862,12 +1853,39 @@ int ObjectRef::l_set_sky(lua_State *L)
                getServer(L)->setMoon(player, moon_params);
                getServer(L)->setStars(player, star_params);
        }
+
        getServer(L)->setSky(player, sky_params);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
+}
+
+static void push_sky_color(lua_State *L, const SkyboxParams &params)
+{
+       lua_newtable(L);
+       if (params.type == "regular") {
+               push_ARGB8(L, params.sky_color.day_sky);
+               lua_setfield(L, -2, "day_sky");
+               push_ARGB8(L, params.sky_color.day_horizon);
+               lua_setfield(L, -2, "day_horizon");
+               push_ARGB8(L, params.sky_color.dawn_sky);
+               lua_setfield(L, -2, "dawn_sky");
+               push_ARGB8(L, params.sky_color.dawn_horizon);
+               lua_setfield(L, -2, "dawn_horizon");
+               push_ARGB8(L, params.sky_color.night_sky);
+               lua_setfield(L, -2, "night_sky");
+               push_ARGB8(L, params.sky_color.night_horizon);
+               lua_setfield(L, -2, "night_horizon");
+               push_ARGB8(L, params.sky_color.indoors);
+               lua_setfield(L, -2, "indoors");
+       }
+       push_ARGB8(L, params.fog_sun_tint);
+       lua_setfield(L, -2, "fog_sun_tint");
+       push_ARGB8(L, params.fog_moon_tint);
+       lua_setfield(L, -2, "fog_moon_tint");
+       lua_pushstring(L, params.fog_tint_type.c_str());
+       lua_setfield(L, -2, "fog_tint_type");
 }
 
-// get_sky(self)
+// get_sky(self, as_table)
 int ObjectRef::l_get_sky(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
@@ -1876,10 +1894,30 @@ int ObjectRef::l_get_sky(lua_State *L)
        if (player == nullptr)
                return 0;
 
-       SkyboxParams skybox_params = player->getSkyParams();
+       const SkyboxParams &skybox_params = player->getSkyParams();
+
+       // handle the deprecated version
+       if (!readParam<bool>(L, 2, false)) {
+               log_deprecated(L, "Deprecated call to get_sky, please check lua_api.txt");
 
+               push_ARGB8(L, skybox_params.bgcolor);
+               lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size());
+
+               lua_newtable(L);
+               s16 i = 1;
+               for (const std::string &texture : skybox_params.textures) {
+                       lua_pushlstring(L, texture.c_str(), texture.size());
+                       lua_rawseti(L, -2, i++);
+               }
+               lua_pushboolean(L, skybox_params.clouds);
+               return 4;
+       }
+
+       lua_newtable(L);
        push_ARGB8(L, skybox_params.bgcolor);
+       lua_setfield(L, -2, "base_color");
        lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size());
+       lua_setfield(L, -2, "type");
 
        lua_newtable(L);
        s16 i = 1;
@@ -1887,44 +1925,30 @@ int ObjectRef::l_get_sky(lua_State *L)
                lua_pushlstring(L, texture.c_str(), texture.size());
                lua_rawseti(L, -2, i++);
        }
+       lua_setfield(L, -2, "textures");
        lua_pushboolean(L, skybox_params.clouds);
-       return 4;
+       lua_setfield(L, -2, "clouds");
+
+       push_sky_color(L, skybox_params);
+       lua_setfield(L, -2, "sky_color");
+       return 1;
 }
 
+// DEPRECATED
 // get_sky_color(self)
 int ObjectRef::l_get_sky_color(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
+
+       log_deprecated(L, "Deprecated call to get_sky_color, use get_sky instead");
+
        ObjectRef *ref = checkobject(L, 1);
        RemotePlayer *player = getplayer(ref);
        if (player == nullptr)
                return 0;
 
        const SkyboxParams &skybox_params = player->getSkyParams();
-
-       lua_newtable(L);
-       if (skybox_params.type == "regular") {
-               push_ARGB8(L, skybox_params.sky_color.day_sky);
-               lua_setfield(L, -2, "day_sky");
-               push_ARGB8(L, skybox_params.sky_color.day_horizon);
-               lua_setfield(L, -2, "day_horizon");
-               push_ARGB8(L, skybox_params.sky_color.dawn_sky);
-               lua_setfield(L, -2, "dawn_sky");
-               push_ARGB8(L, skybox_params.sky_color.dawn_horizon);
-               lua_setfield(L, -2, "dawn_horizon");
-               push_ARGB8(L, skybox_params.sky_color.night_sky);
-               lua_setfield(L, -2, "night_sky");
-               push_ARGB8(L, skybox_params.sky_color.night_horizon);
-               lua_setfield(L, -2, "night_horizon");
-               push_ARGB8(L, skybox_params.sky_color.indoors);
-               lua_setfield(L, -2, "indoors");
-       }
-       push_ARGB8(L, skybox_params.fog_sun_tint);
-       lua_setfield(L, -2, "fog_sun_tint");
-       push_ARGB8(L, skybox_params.fog_moon_tint);
-       lua_setfield(L, -2, "fog_moon_tint");
-       lua_pushstring(L, skybox_params.fog_tint_type.c_str());
-       lua_setfield(L, -2, "fog_tint_type");
+       push_sky_color(L, skybox_params);
        return 1;
 }
 
@@ -1937,25 +1961,23 @@ int ObjectRef::l_set_sun(lua_State *L)
        if (player == nullptr)
                return 0;
 
-       luaL_checktype(L, 2, LUA_TTABLE);
        SunParams sun_params = player->getSunParams();
 
-       sun_params.visible = getboolfield_default(L, 2,
-                       "visible", sun_params.visible);
-       sun_params.texture = getstringfield_default(L, 2,
-                       "texture", sun_params.texture);
-       sun_params.tonemap = getstringfield_default(L, 2,
-                       "tonemap", sun_params.tonemap);
-       sun_params.sunrise = getstringfield_default(L, 2,
-                       "sunrise", sun_params.sunrise);
-       sun_params.sunrise_visible = getboolfield_default(L, 2,
-                       "sunrise_visible", sun_params.sunrise_visible);
-       sun_params.scale = getfloatfield_default(L, 2,
-                       "scale", sun_params.scale);
+       // reset if empty
+       if (lua_isnoneornil(L, 2)) {
+               sun_params = SkyboxDefaults::getSunDefaults();
+       } else {
+               luaL_checktype(L, 2, LUA_TTABLE);
+               sun_params.visible = getboolfield_default(L, 2,   "visible", sun_params.visible);
+               sun_params.texture = getstringfield_default(L, 2, "texture", sun_params.texture);
+               sun_params.tonemap = getstringfield_default(L, 2, "tonemap", sun_params.tonemap);
+               sun_params.sunrise = getstringfield_default(L, 2, "sunrise", sun_params.sunrise);
+               sun_params.sunrise_visible = getboolfield_default(L, 2, "sunrise_visible", sun_params.sunrise_visible);
+               sun_params.scale   = getfloatfield_default(L, 2,  "scale",   sun_params.scale);
+       }
 
        getServer(L)->setSun(player, sun_params);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 //get_sun(self)
@@ -1994,21 +2016,21 @@ int ObjectRef::l_set_moon(lua_State *L)
        if (player == nullptr)
                return 0;
 
-       luaL_checktype(L, 2, LUA_TTABLE);
        MoonParams moon_params = player->getMoonParams();
 
-       moon_params.visible = getboolfield_default(L, 2,
-               "visible", moon_params.visible);
-       moon_params.texture = getstringfield_default(L, 2,
-               "texture", moon_params.texture);
-       moon_params.tonemap = getstringfield_default(L, 2,
-               "tonemap", moon_params.tonemap);
-       moon_params.scale = getfloatfield_default(L, 2,
-               "scale", moon_params.scale);
+       // reset if empty
+       if (lua_isnoneornil(L, 2)) {
+               moon_params = SkyboxDefaults::getMoonDefaults();
+       } else {
+               luaL_checktype(L, 2, LUA_TTABLE);
+               moon_params.visible = getboolfield_default(L, 2,   "visible", moon_params.visible);
+               moon_params.texture = getstringfield_default(L, 2, "texture", moon_params.texture);
+               moon_params.tonemap = getstringfield_default(L, 2, "tonemap", moon_params.tonemap);
+               moon_params.scale   = getfloatfield_default(L, 2,  "scale",   moon_params.scale);
+       }
 
        getServer(L)->setMoon(player, moon_params);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_moon(self)
@@ -2043,25 +2065,27 @@ int ObjectRef::l_set_stars(lua_State *L)
        if (player == nullptr)
                return 0;
 
-       luaL_checktype(L, 2, LUA_TTABLE);
        StarParams star_params = player->getStarParams();
 
-       star_params.visible = getboolfield_default(L, 2,
-               "visible", star_params.visible);
-       star_params.count = getintfield_default(L, 2,
-               "count", star_params.count);
+       // reset if empty
+       if (lua_isnoneornil(L, 2)) {
+               star_params = SkyboxDefaults::getStarDefaults();
+       } else {
+               luaL_checktype(L, 2, LUA_TTABLE);
+               star_params.visible = getboolfield_default(L, 2, "visible", star_params.visible);
+               star_params.count   = getintfield_default(L, 2,  "count",   star_params.count);
 
-       lua_getfield(L, 2, "star_color");
-       if (!lua_isnil(L, -1))
-               read_color(L, -1, &star_params.starcolor);
-       lua_pop(L, 1);
+               lua_getfield(L, 2, "star_color");
+               if (!lua_isnil(L, -1))
+                       read_color(L, -1, &star_params.starcolor);
+               lua_pop(L, 1);
 
-       star_params.scale = getfloatfield_default(L, 2,
-               "scale", star_params.scale);
+               star_params.scale = getfloatfield_default(L, 2,
+                       "scale", star_params.scale);
+       }
 
        getServer(L)->setStars(player, star_params);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_stars(self)
@@ -2096,35 +2120,39 @@ int ObjectRef::l_set_clouds(lua_State *L)
        if (player == nullptr)
                return 0;
 
-       luaL_checktype(L, 2, LUA_TTABLE);
        CloudParams cloud_params = player->getCloudParams();
 
-       cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density);
+       // reset if empty
+       if (lua_isnoneornil(L, 2)) {
+               cloud_params = SkyboxDefaults::getCloudDefaults();
+       } else {
+               luaL_checktype(L, 2, LUA_TTABLE);
+               cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density);
 
-       lua_getfield(L, 2, "color");
-       if (!lua_isnil(L, -1))
-               read_color(L, -1, &cloud_params.color_bright);
-       lua_pop(L, 1);
-       lua_getfield(L, 2, "ambient");
-       if (!lua_isnil(L, -1))
-               read_color(L, -1, &cloud_params.color_ambient);
-       lua_pop(L, 1);
+               lua_getfield(L, 2, "color");
+               if (!lua_isnil(L, -1))
+                       read_color(L, -1, &cloud_params.color_bright);
+               lua_pop(L, 1);
+               lua_getfield(L, 2, "ambient");
+               if (!lua_isnil(L, -1))
+                       read_color(L, -1, &cloud_params.color_ambient);
+               lua_pop(L, 1);
 
-       cloud_params.height    = getfloatfield_default(L, 2, "height",    cloud_params.height   );
-       cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
+               cloud_params.height    = getfloatfield_default(L, 2, "height",    cloud_params.height);
+               cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
 
-       lua_getfield(L, 2, "speed");
-       if (lua_istable(L, -1)) {
-               v2f new_speed;
-               new_speed.X = getfloatfield_default(L, -1, "x", 0);
-               new_speed.Y = getfloatfield_default(L, -1, "z", 0);
-               cloud_params.speed = new_speed;
+               lua_getfield(L, 2, "speed");
+               if (lua_istable(L, -1)) {
+                       v2f new_speed;
+                       new_speed.X = getfloatfield_default(L, -1, "x", 0);
+                       new_speed.Y = getfloatfield_default(L, -1, "z", 0);
+                       cloud_params.speed = new_speed;
+               }
+               lua_pop(L, 1);
        }
-       lua_pop(L, 1);
 
        getServer(L)->setClouds(player, cloud_params);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 int ObjectRef::l_get_clouds(lua_State *L)
@@ -2178,8 +2206,7 @@ int ObjectRef::l_override_day_night_ratio(lua_State *L)
        }
 
        getServer(L)->overrideDayNightRatio(player, do_override, ratio);
-       lua_pushboolean(L, true);
-       return 1;
+       return 0;
 }
 
 // get_day_night_ratio(self)
@@ -2256,6 +2283,46 @@ int ObjectRef::l_set_minimap_modes(lua_State *L)
        return 0;
 }
 
+// set_lighting(self, lighting)
+int ObjectRef::l_set_lighting(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       ObjectRef *ref = checkobject(L, 1);
+       RemotePlayer *player = getplayer(ref);
+       if (player == nullptr)
+               return 0;
+
+       luaL_checktype(L, 2, LUA_TTABLE);
+       Lighting lighting = player->getLighting();
+       lua_getfield(L, 2, "shadows");
+       if (lua_istable(L, -1)) {
+               lighting.shadow_intensity = getfloatfield_default(L, -1, "intensity",    lighting.shadow_intensity);
+       }
+       lua_pop(L, -1);
+
+       getServer(L)->setLighting(player, lighting);
+       return 0;
+}
+
+// get_lighting(self)
+int ObjectRef::l_get_lighting(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       ObjectRef *ref = checkobject(L, 1);
+       RemotePlayer *player = getplayer(ref);
+       if (player == nullptr)
+               return 0;
+
+       const Lighting &lighting = player->getLighting();
+
+       lua_newtable(L); // result
+       lua_newtable(L); // "shadows"
+       lua_pushnumber(L, lighting.shadow_intensity);
+       lua_setfield(L, -2, "intensity");
+       lua_setfield(L, -2, "shadows");
+       return 1;
+}
+
 ObjectRef::ObjectRef(ServerActiveObject *object):
        m_object(object)
 {}
@@ -2409,5 +2476,7 @@ luaL_Reg ObjectRef::methods[] = {
        luamethod(ObjectRef, get_eye_offset),
        luamethod(ObjectRef, send_mapblock),
        luamethod(ObjectRef, set_minimap_modes),
+       luamethod(ObjectRef, set_lighting),
+       luamethod(ObjectRef, get_lighting),
        {0,0}
 };
index db3a3a7cfe7c36d0f17bf0ff04be4b0d99ca89bb..3e4e6681a122b4b9ec80b7756b452dd133cfa971 100644 (file)
@@ -316,9 +316,10 @@ class ObjectRef : public ModApiBase {
        // set_sky(self, sky_parameters)
        static int l_set_sky(lua_State *L);
 
-       // get_sky(self)
+       // get_sky(self, as_table)
        static int l_get_sky(lua_State *L);
 
+       // DEPRECATED
        // get_sky_color(self)
        static int l_get_sky_color(lua_State* L);
 
@@ -375,4 +376,10 @@ class ObjectRef : public ModApiBase {
 
        // set_minimap_modes(self, modes, wanted_mode)
        static int l_set_minimap_modes(lua_State *L);
+
+       // set_lighting(self, lighting)
+       static int l_set_lighting(lua_State *L);
+       
+       // get_lighting(self)
+       static int l_get_lighting(lua_State *L);
 };
index b4672fe2a4a4b69a15429545767da77306a82d8a..e8105dd750039e0de35214b2917dcf1071505e1d 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_internal.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
+#include "common/c_packer.h"
 #include "cpp_api/s_base.h"
 #include "cpp_api/s_security.h"
 #include "scripting_server.h"
@@ -57,6 +58,14 @@ int ModApiServer::l_get_server_uptime(lua_State *L)
        return 1;
 }
 
+// get_server_max_lag()
+int ModApiServer::l_get_server_max_lag(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       GET_ENV_PTR;
+       lua_pushnumber(L, env->getMaxLagEstimate());
+       return 1;
+}
 
 // print(text)
 int ModApiServer::l_print(lua_State *L)
@@ -282,8 +291,10 @@ int ModApiServer::l_ban_player(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
 
-       Server *server = getServer(L);
+       if (!getEnv(L))
+               throw LuaError("Can't ban player before server has started up");
 
+       Server *server = getServer(L);
        const char *name = luaL_checkstring(L, 1);
        RemotePlayer *player = server->getEnv().getPlayer(name);
        if (!player) {
@@ -297,23 +308,30 @@ int ModApiServer::l_ban_player(lua_State *L)
        return 1;
 }
 
-// kick_player(name, [reason]) -> success
-int ModApiServer::l_kick_player(lua_State *L)
+// disconnect_player(name, [reason]) -> success
+int ModApiServer::l_disconnect_player(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
+
+       if (!getEnv(L))
+               throw LuaError("Can't kick player before server has started up");
+
        const char *name = luaL_checkstring(L, 1);
-       std::string message("Kicked");
+       std::string message;
        if (lua_isstring(L, 2))
-               message.append(": ").append(readParam<std::string>(L, 2));
+               message.append(readParam<std::string>(L, 2));
        else
-               message.append(".");
+               message.append("Disconnected.");
+
+       Server *server = getServer(L);
 
-       RemotePlayer *player = dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name);
-       if (player == NULL) {
+       RemotePlayer *player = server->getEnv().getPlayer(name);
+       if (!player) {
                lua_pushboolean(L, false); // No such player
                return 1;
        }
-       getServer(L)->DenyAccess_Legacy(player->getPeerId(), utf8_to_wide(message));
+
+       server->DenyAccess(player->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING, message);
        lua_pushboolean(L, true);
        return 1;
 }
@@ -324,7 +342,8 @@ int ModApiServer::l_remove_player(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        std::string name = luaL_checkstring(L, 1);
        ServerEnvironment *s_env = dynamic_cast<ServerEnvironment *>(getEnv(L));
-       assert(s_env);
+       if (!s_env)
+               throw LuaError("Can't remove player before server has started up");
 
        RemotePlayer *player = s_env->getPlayer(name.c_str());
        if (!player)
@@ -375,12 +394,11 @@ int ModApiServer::l_get_modpath(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
        std::string modname = luaL_checkstring(L, 1);
-       const ModSpec *mod = getServer(L)->getModSpec(modname);
-       if (!mod) {
+       const ModSpec *mod = getGameDef(L)->getModSpec(modname);
+       if (!mod)
                lua_pushnil(L);
-               return 1;
-       }
-       lua_pushstring(L, mod->path.c_str());
+       else
+               lua_pushstring(L, mod->path.c_str());
        return 1;
 }
 
@@ -392,13 +410,14 @@ int ModApiServer::l_get_modnames(lua_State *L)
 
        // Get a list of mods
        std::vector<std::string> modlist;
-       getServer(L)->getModNames(modlist);
+       for (auto &it : getGameDef(L)->getMods())
+               modlist.emplace_back(it.name);
 
        std::sort(modlist.begin(), modlist.end());
 
        // Package them up for Lua
        lua_createtable(L, modlist.size(), 0);
-       std::vector<std::string>::iterator iter = modlist.begin();
+       auto iter = modlist.begin();
        for (u16 i = 0; iter != modlist.end(); ++iter) {
                lua_pushstring(L, iter->c_str());
                lua_rawseti(L, -2, ++i);
@@ -410,8 +429,8 @@ int ModApiServer::l_get_modnames(lua_State *L)
 int ModApiServer::l_get_worldpath(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
-       std::string worldpath = getServer(L)->getWorldPath();
-       lua_pushstring(L, worldpath.c_str());
+       const Server *srv = getServer(L);
+       lua_pushstring(L, srv->getWorldPath().c_str());
        return 1;
 }
 
@@ -479,7 +498,7 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
 
        CHECK_SECURE_PATH(L, filepath.c_str(), false);
 
-       u32 token = server->getScriptIface()->allocateDynamicMediaCallback(2);
+       u32 token = server->getScriptIface()->allocateDynamicMediaCallback(L, 2);
 
        bool ok = server->dynamicAddMedia(filepath, token, to_player, ephemeral);
        if (!ok)
@@ -493,7 +512,8 @@ int ModApiServer::l_dynamic_add_media(lua_State *L)
 int ModApiServer::l_is_singleplayer(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
-       lua_pushboolean(L, getServer(L)->isSingleplayer());
+       const Server *srv = getServer(L);
+       lua_pushboolean(L, srv->isSingleplayer());
        return 1;
 }
 
@@ -508,11 +528,82 @@ int ModApiServer::l_notify_authentication_modified(lua_State *L)
        return 0;
 }
 
+// do_async_callback(func, params, mod_origin)
+int ModApiServer::l_do_async_callback(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       ServerScripting *script = getScriptApi<ServerScripting>(L);
+
+       luaL_checktype(L, 1, LUA_TFUNCTION);
+       luaL_checktype(L, 2, LUA_TTABLE);
+       luaL_checktype(L, 3, LUA_TSTRING);
+
+       call_string_dump(L, 1);
+       size_t func_length;
+       const char *serialized_func_raw = lua_tolstring(L, -1, &func_length);
+
+       PackedValue *param = script_pack(L, 2);
+
+       std::string mod_origin = readParam<std::string>(L, 3);
+
+       u32 jobId = script->queueAsync(
+               std::string(serialized_func_raw, func_length),
+               param, mod_origin);
+
+       lua_settop(L, 0);
+       lua_pushinteger(L, jobId);
+       return 1;
+}
+
+// register_async_dofile(path)
+int ModApiServer::l_register_async_dofile(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       std::string path = readParam<std::string>(L, 1);
+       CHECK_SECURE_PATH(L, path.c_str(), false);
+
+       // Find currently running mod name (only at init time)
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
+       if (!lua_isstring(L, -1))
+               return 0;
+       std::string modname = readParam<std::string>(L, -1);
+
+       getServer(L)->m_async_init_files.emplace_back(modname, path);
+       lua_pushboolean(L, true);
+       return 1;
+}
+
+// serialize_roundtrip(value)
+// Meant for unit testing the packer from Lua
+int ModApiServer::l_serialize_roundtrip(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       int top = lua_gettop(L);
+       auto *pv = script_pack(L, 1);
+       if (top != lua_gettop(L))
+               throw LuaError("stack values leaked");
+
+#ifndef NDEBUG
+       script_dump_packed(pv);
+#endif
+
+       top = lua_gettop(L);
+       script_unpack(L, pv);
+       delete pv;
+       if (top + 1 != lua_gettop(L))
+               throw LuaError("stack values leaked");
+
+       return 1;
+}
+
 void ModApiServer::Initialize(lua_State *L, int top)
 {
        API_FCT(request_shutdown);
        API_FCT(get_server_status);
        API_FCT(get_server_uptime);
+       API_FCT(get_server_max_lag);
        API_FCT(get_worldpath);
        API_FCT(is_singleplayer);
 
@@ -536,7 +627,22 @@ void ModApiServer::Initialize(lua_State *L, int top)
        API_FCT(get_ban_list);
        API_FCT(get_ban_description);
        API_FCT(ban_player);
-       API_FCT(kick_player);
+       API_FCT(disconnect_player);
+       API_FCT(remove_player);
        API_FCT(unban_player_or_ip);
        API_FCT(notify_authentication_modified);
+
+       API_FCT(do_async_callback);
+       API_FCT(register_async_dofile);
+       API_FCT(serialize_roundtrip);
+}
+
+void ModApiServer::InitializeAsync(lua_State *L, int top)
+{
+       API_FCT(get_worldpath);
+       API_FCT(is_singleplayer);
+
+       API_FCT(get_current_modname);
+       API_FCT(get_modpath);
+       API_FCT(get_modnames);
 }
index c688e494b9be0393c7765711bd5ebac18f4d7cbb..a4f38c34e7d7c06581f0c58e05d7e2753b52d995 100644 (file)
@@ -33,6 +33,9 @@ class ModApiServer : public ModApiBase
        // get_server_uptime()
        static int l_get_server_uptime(lua_State *L);
 
+       // get_server_max_lag()
+       static int l_get_server_max_lag(lua_State *L);
+
        // get_worldpath()
        static int l_get_worldpath(lua_State *L);
 
@@ -94,8 +97,8 @@ class ModApiServer : public ModApiBase
        // unban_player_or_ip()
        static int l_unban_player_or_ip(lua_State *L);
 
-       // kick_player(name, [message]) -> success
-       static int l_kick_player(lua_State *L);
+       // disconnect_player(name, [reason]) -> success
+       static int l_disconnect_player(lua_State *L);
 
        // remove_player(name)
        static int l_remove_player(lua_State *L);
@@ -103,6 +106,16 @@ class ModApiServer : public ModApiBase
        // notify_authentication_modified(name)
        static int l_notify_authentication_modified(lua_State *L);
 
+       // do_async_callback(func, params, mod_origin)
+       static int l_do_async_callback(lua_State *L);
+
+       // register_async_dofile(path)
+       static int l_register_async_dofile(lua_State *L);
+
+       // serialize_roundtrip(obj)
+       static int l_serialize_roundtrip(lua_State *L);
+
 public:
        static void Initialize(lua_State *L, int top);
+       static void InitializeAsync(lua_State *L, int top);
 };
index 978b315d58f0d2d11536f25709f669b54360caf7..b8f4347a88c814549a45aa04dbca6cb3608d720b 100644 (file)
@@ -32,19 +32,23 @@ int ModApiStorage::l_get_mod_storage(lua_State *L)
 
        std::string mod_name = readParam<std::string>(L, -1);
 
-       ModMetadata *store = new ModMetadata(mod_name);
+       ModMetadata *store = nullptr;
+
        if (IGameDef *gamedef = getGameDef(L)) {
-               store->load(gamedef->getModStoragePath());
-               gamedef->registerModStorage(store);
+               store = new ModMetadata(mod_name, gamedef->getModStorageDatabase());
+               if (gamedef->registerModStorage(store)) {
+                       StorageRef::create(L, store);
+                       int object = lua_gettop(L);
+                       lua_pushvalue(L, object);
+                       return 1;
+               }
        } else {
-               delete store;
                assert(false); // this should not happen
        }
 
-       StorageRef::create(L, store);
-       int object = lua_gettop(L);
+       delete store;
 
-       lua_pushvalue(L, object);
+       lua_pushnil(L);
        return 1;
 }
 
index d575eb6037017e7a6ea0d73501fc58d1fb548922..fa749c2e5104ce6174bc7f854e05164d3e94d5ef 100644 (file)
@@ -41,7 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/hex.h"
 #include "util/sha1.h"
 #include "util/png.h"
-#include <algorithm>
 #include <cstdio>
 
 // log([level,] text)
@@ -160,28 +159,33 @@ int ModApiUtil::l_write_json(lua_State *L)
        return 1;
 }
 
-// get_dig_params(groups, tool_capabilities)
+// get_dig_params(groups, tool_capabilities[, wear])
 int ModApiUtil::l_get_dig_params(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
        ItemGroupList groups;
        read_groups(L, 1, groups);
        ToolCapabilities tp = read_tool_capabilities(L, 2);
-       push_dig_params(L, getDigParams(groups, &tp));
+       if (lua_isnoneornil(L, 3)) {
+               push_dig_params(L, getDigParams(groups, &tp));
+       } else {
+               u16 wear = readParam<int>(L, 3);
+               push_dig_params(L, getDigParams(groups, &tp, wear));
+       }
        return 1;
 }
 
-// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
+// get_hit_params(groups, tool_capabilities[, time_from_last_punch, [, wear]])
 int ModApiUtil::l_get_hit_params(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
        std::unordered_map<std::string, int> groups;
        read_groups(L, 1, groups);
        ToolCapabilities tp = read_tool_capabilities(L, 2);
-       if(lua_isnoneornil(L, 3))
-               push_hit_params(L, getHitParams(groups, &tp));
-       else
-               push_hit_params(L, getHitParams(groups, &tp, readParam<float>(L, 3)));
+       float time_from_last_punch = readParam<float>(L, 3, 1000000);
+       int wear = readParam<int>(L, 4, 0);
+       push_hit_params(L, getHitParams(groups, &tp,
+               time_from_last_punch, wear));
        return 1;
 }
 
@@ -344,6 +348,49 @@ int ModApiUtil::l_mkdir(lua_State *L)
        return 1;
 }
 
+// rmdir(path, recursive)
+int ModApiUtil::l_rmdir(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *path = luaL_checkstring(L, 1);
+       CHECK_SECURE_PATH(L, path, true);
+
+       bool recursive = readParam<bool>(L, 2, false);
+
+       if (recursive)
+               lua_pushboolean(L, fs::RecursiveDelete(path));
+       else
+               lua_pushboolean(L, fs::DeleteSingleFileOrEmptyDirectory(path));
+
+       return 1;
+}
+
+// cpdir(source, destination)
+int ModApiUtil::l_cpdir(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *source = luaL_checkstring(L, 1);
+       const char *destination = luaL_checkstring(L, 2);
+       CHECK_SECURE_PATH(L, source, false);
+       CHECK_SECURE_PATH(L, destination, true);
+
+       lua_pushboolean(L, fs::CopyDir(source, destination));
+       return 1;
+}
+
+// mpdir(source, destination)
+int ModApiUtil::l_mvdir(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *source = luaL_checkstring(L, 1);
+       const char *destination = luaL_checkstring(L, 2);
+       CHECK_SECURE_PATH(L, source, true);
+       CHECK_SECURE_PATH(L, destination, true);
+
+       lua_pushboolean(L, fs::MoveDir(source, destination));
+       return 1;
+}
+
 // get_dir_list(path, is_dir)
 int ModApiUtil::l_get_dir_list(lua_State *L)
 {
@@ -396,36 +443,7 @@ int ModApiUtil::l_request_insecure_environment(lua_State *L)
                return 1;
        }
 
-       // We have to make sure that this function is being called directly by
-       // a mod, otherwise a malicious mod could override this function and
-       // steal its return value.
-       lua_Debug info;
-       // Make sure there's only one item below this function on the stack...
-       if (lua_getstack(L, 2, &info)) {
-               return 0;
-       }
-       FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed");
-       FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed");
-       // ...and that that item is the main file scope.
-       if (strcmp(info.what, "main") != 0) {
-               return 0;
-       }
-
-       // Get mod name
-       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
-       if (!lua_isstring(L, -1)) {
-               return 0;
-       }
-
-       // Check secure.trusted_mods
-       std::string mod_name = readParam<std::string>(L, -1);
-       std::string trusted_mods = g_settings->get("secure.trusted_mods");
-       trusted_mods.erase(std::remove_if(trusted_mods.begin(),
-                       trusted_mods.end(), static_cast<int(*)(int)>(&std::isspace)),
-                       trusted_mods.end());
-       std::vector<std::string> mod_list = str_split(trusted_mods, ',');
-       if (std::find(mod_list.begin(), mod_list.end(), mod_name) ==
-                       mod_list.end()) {
+       if (!ScriptApiSecurity::checkWhitelisted(L, "secure.trusted_mods")) {
                return 0;
        }
 
@@ -583,6 +601,9 @@ void ModApiUtil::Initialize(lua_State *L, int top)
        API_FCT(decompress);
 
        API_FCT(mkdir);
+       API_FCT(rmdir);
+       API_FCT(cpdir);
+       API_FCT(mvdir);
        API_FCT(get_dir_list);
        API_FCT(safe_file_write);
 
@@ -651,7 +672,13 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
        API_FCT(decompress);
 
        API_FCT(mkdir);
+       API_FCT(rmdir);
+       API_FCT(cpdir);
+       API_FCT(mvdir);
        API_FCT(get_dir_list);
+       API_FCT(safe_file_write);
+
+       API_FCT(request_insecure_environment);
 
        API_FCT(encode_base64);
        API_FCT(decode_base64);
@@ -661,6 +688,8 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
        API_FCT(colorspec_to_colorstring);
        API_FCT(colorspec_to_bytes);
 
+       API_FCT(encode_png);
+
        API_FCT(get_last_run_mod);
        API_FCT(set_last_run_mod);
 
index cc91e8d399764440a4c4cd4b41d6c794b246ecb7..cc55635776bddb00f03b0e0e43ba3c20ebb24a93 100644 (file)
@@ -50,10 +50,10 @@ class ModApiUtil : public ModApiBase
        // write_json(data[, styled])
        static int l_write_json(lua_State *L);
 
-       // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
+       // get_dig_params(groups, tool_capabilities[, wear])
        static int l_get_dig_params(lua_State *L);
 
-       // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
+       // get_hit_params(groups, tool_capabilities[, time_from_last_punch[, wear]])
        static int l_get_hit_params(lua_State *L);
 
        // check_password_entry(name, entry, password)
@@ -80,6 +80,15 @@ class ModApiUtil : public ModApiBase
        // mkdir(path)
        static int l_mkdir(lua_State *L);
 
+       // rmdir(path, recursive)
+       static int l_rmdir(lua_State *L);
+
+       // cpdir(source, destination, remove_source)
+       static int l_cpdir(lua_State *L);
+
+       // mvdir(source, destination)
+       static int l_mvdir(lua_State *L);
+
        // get_dir_list(path, is_dir)
        static int l_get_dir_list(lua_State *L);
 
@@ -120,6 +129,4 @@ class ModApiUtil : public ModApiBase
        static void Initialize(lua_State *L, int top);
        static void InitializeAsync(lua_State *L, int top);
        static void InitializeClient(lua_State *L, int top);
-
-       static void InitializeAsync(AsyncEngine &engine);
 };
index e040e545bb5bc4c3c34d08f873480cea22cbf0ae..6187a47db2c2b238605702201e021c5d2d96a6cc 100644 (file)
@@ -17,11 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-
+#include <map>
 #include "lua_api/l_vmanip.h"
 #include "lua_api/l_internal.h"
 #include "common/c_content.h"
 #include "common/c_converter.h"
+#include "common/c_packer.h"
 #include "emerge.h"
 #include "environment.h"
 #include "map.h"
@@ -45,6 +46,8 @@ int LuaVoxelManip::l_read_from_map(lua_State *L)
 
        LuaVoxelManip *o = checkobject(L, 1);
        MMVManip *vm = o->vm;
+       if (vm->isOrphan())
+               return 0;
 
        v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 2));
        v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 3));
@@ -112,23 +115,23 @@ int LuaVoxelManip::l_write_to_map(lua_State *L)
 
        LuaVoxelManip *o = checkobject(L, 1);
        bool update_light = !lua_isboolean(L, 2) || readParam<bool>(L, 2);
+
        GET_ENV_PTR;
        ServerMap *map = &(env->getServerMap());
+
+       std::map<v3s16, MapBlock*> modified_blocks;
        if (o->is_mapgen_vm || !update_light) {
-               o->vm->blitBackAll(&(o->modified_blocks));
+               o->vm->blitBackAll(&modified_blocks);
        } else {
-               voxalgo::blit_back_with_light(map, o->vm,
-                       &(o->modified_blocks));
+               voxalgo::blit_back_with_light(map, o->vm, &modified_blocks);
        }
 
        MapEditEvent event;
        event.type = MEET_OTHER;
-       for (const auto &modified_block : o->modified_blocks)
-               event.modified_blocks.insert(modified_block.first);
-
+       for (const auto &it : modified_blocks)
+               event.modified_blocks.insert(it.first);
        map->dispatchEvent(event);
 
-       o->modified_blocks.clear();
        return 0;
 }
 
@@ -166,7 +169,7 @@ int LuaVoxelManip::l_update_liquids(lua_State *L)
 
        LuaVoxelManip *o = checkobject(L, 1);
 
-       Map *map = &(env->getMap());
+       ServerMap *map = &(env->getServerMap());
        const NodeDefManager *ndef = getServer(L)->getNodeDefManager();
        MMVManip *vm = o->vm;
 
@@ -429,6 +432,34 @@ LuaVoxelManip *LuaVoxelManip::checkobject(lua_State *L, int narg)
        return *(LuaVoxelManip **)ud;  // unbox pointer
 }
 
+void *LuaVoxelManip::packIn(lua_State *L, int idx)
+{
+       LuaVoxelManip *o = checkobject(L, idx);
+
+       if (o->is_mapgen_vm)
+               throw LuaError("nope");
+       return o->vm->clone();
+}
+
+void LuaVoxelManip::packOut(lua_State *L, void *ptr)
+{
+       MMVManip *vm = reinterpret_cast<MMVManip*>(ptr);
+       if (!L) {
+               delete vm;
+               return;
+       }
+
+       // Associate vmanip with map if the Lua env has one
+       Environment *env = getEnv(L);
+       if (env)
+               vm->reparent(&(env->getMap()));
+
+       LuaVoxelManip *o = new LuaVoxelManip(vm, false);
+       *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+       luaL_getmetatable(L, className);
+       lua_setmetatable(L, -2);
+}
+
 void LuaVoxelManip::Register(lua_State *L)
 {
        lua_newtable(L);
@@ -455,6 +486,8 @@ void LuaVoxelManip::Register(lua_State *L)
 
        // Can be created from Lua (VoxelManip())
        lua_register(L, className, create_object);
+
+       script_register_packer(L, className, packIn, packOut);
 }
 
 const char LuaVoxelManip::className[] = "VoxelManip";
index 15ab9eef8c2fc8717604c038b3fa0bdefb8ae789..00513333567c142d817967efc514481e44ddfbd5 100644 (file)
@@ -19,7 +19,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #pragma once
 
-#include <map>
 #include "irr_v3d.h"
 #include "lua_api/l_base.h"
 
@@ -33,7 +32,6 @@ class MMVManip;
 class LuaVoxelManip : public ModApiBase
 {
 private:
-       std::map<v3s16, MapBlock *> modified_blocks;
        bool is_mapgen_vm = false;
 
        static const char className[];
@@ -77,5 +75,8 @@ class LuaVoxelManip : public ModApiBase
 
        static LuaVoxelManip *checkobject(lua_State *L, int narg);
 
+       static void *packIn(lua_State *L, int idx);
+       static void packOut(lua_State *L, void *ptr);
+
        static void Register(lua_State *L);
 };
index 85411ded460e5f68b885014544f94d068c72219d..b462141b09ec0b9068a0b5705b53e8a78bbe24b5 100644 (file)
@@ -47,11 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_storage.h"
 
 extern "C" {
-#include "lualib.h"
+#include <lualib.h>
 }
 
 ServerScripting::ServerScripting(Server* server):
-               ScriptApiBase(ScriptingType::Server)
+               ScriptApiBase(ScriptingType::Server),
+               asyncEngine(server)
 {
        setGameDef(server);
 
@@ -88,6 +89,48 @@ ServerScripting::ServerScripting(Server* server):
        infostream << "SCRIPTAPI: Initialized game modules" << std::endl;
 }
 
+void ServerScripting::initAsync()
+{
+       // Save globals to transfer
+       {
+               lua_State *L = getStack();
+               lua_getglobal(L, "core");
+               luaL_checktype(L, -1, LUA_TTABLE);
+               lua_getfield(L, -1, "get_globals_to_transfer");
+               lua_call(L, 0, 1);
+               auto *data = script_pack(L, -1);
+               assert(!data->contains_userdata);
+               getServer()->m_async_globals_data.reset(data);
+               lua_pushnil(L);
+               lua_setfield(L, -3, "get_globals_to_transfer"); // unset function too
+               lua_pop(L, 2); // pop 'core', return value
+       }
+
+       infostream << "SCRIPTAPI: Initializing async engine" << std::endl;
+       asyncEngine.registerStateInitializer(InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiUtil::InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiCraft::InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiItemMod::InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiServer::InitializeAsync);
+       // not added: ModApiMapgen is a minefield for thread safety
+       // not added: ModApiHttp async api can't really work together with our jobs
+       // not added: ModApiStorage is probably not thread safe(?)
+
+       asyncEngine.initialize(0);
+}
+
+void ServerScripting::stepAsync()
+{
+       asyncEngine.step(getStack());
+}
+
+u32 ServerScripting::queueAsync(std::string &&serialized_func,
+       PackedValue *param, const std::string &mod_origin)
+{
+       return asyncEngine.queueAsyncJob(std::move(serialized_func),
+                       param, mod_origin);
+}
+
 void ServerScripting::InitializeModApi(lua_State *L, int top)
 {
        // Register reference classes (userdata)
@@ -125,3 +168,24 @@ void ServerScripting::InitializeModApi(lua_State *L, int top)
        ModApiStorage::Initialize(L, top);
        ModApiChannels::Initialize(L, top);
 }
+
+void ServerScripting::InitializeAsync(lua_State *L, int top)
+{
+       // classes
+       LuaItemStack::Register(L);
+       LuaPerlinNoise::Register(L);
+       LuaPerlinNoiseMap::Register(L);
+       LuaPseudoRandom::Register(L);
+       LuaPcgRandom::Register(L);
+       LuaSecureRandom::Register(L);
+       LuaVoxelManip::Register(L);
+       LuaSettings::Register(L);
+
+       // globals data
+       lua_getglobal(L, "core");
+       luaL_checktype(L, -1, LUA_TTABLE);
+       auto *data = ModApiBase::getServer(L)->m_async_globals_data.get();
+       script_unpack(L, data);
+       lua_setfield(L, -2, "transferred_globals");
+       lua_pop(L, 1); // pop 'core'
+}
index bf06ab197fc49fe8e7ac088d24b2c4d84b1102f5..9803397c5390fa1a39a32c3003e1c12253f357f2 100644 (file)
@@ -27,6 +27,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "cpp_api/s_player.h"
 #include "cpp_api/s_server.h"
 #include "cpp_api/s_security.h"
+#include "cpp_api/s_async.h"
+
+struct PackedValue;
 
 /*****************************************************************************/
 /* Scripting <-> Server Game Interface                                       */
@@ -48,6 +51,20 @@ class ServerScripting:
 
        // use ScriptApiBase::loadMod() to load mods
 
+       // Initialize async engine, call this AFTER loading all mods
+       void initAsync();
+
+       // Global step handler to collect async results
+       void stepAsync();
+
+       // Pass job to async threads
+       u32 queueAsync(std::string &&serialized_func,
+               PackedValue *param, const std::string &mod_origin);
+
 private:
        void InitializeModApi(lua_State *L, int top);
+
+       static void InitializeAsync(lua_State *L, int top);
+
+       AsyncEngine asyncEngine;
 };
index b6ce3b37fe06570012661bbcd7e037523f78edfc..11164a0ede10952f78b174a008f8df7996dfceaa 100644 (file)
@@ -108,7 +108,6 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
        char output_buffer[bufsize];
        int status = 0;
        int ret;
-       int bytes_read = 0;
        int bytes_written = 0;
        int input_buffer_len = 0;
 
@@ -122,8 +121,6 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
 
        z.avail_in = 0;
 
-       //dstream<<"initial fail="<<is.fail()<<" bad="<<is.bad()<<std::endl;
-
        for(;;)
        {
                int output_size = bufsize;
@@ -147,19 +144,13 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
                        is.read(input_buffer, bufsize);
                        input_buffer_len = is.gcount();
                        z.avail_in = input_buffer_len;
-                       //dstream<<"read fail="<<is.fail()<<" bad="<<is.bad()<<std::endl;
                }
                if(z.avail_in == 0)
                {
-                       //dstream<<"z.avail_in == 0"<<std::endl;
                        break;
                }
 
-               //dstream<<"1 z.avail_in="<<z.avail_in<<std::endl;
                status = inflate(&z, Z_NO_FLUSH);
-               //dstream<<"2 z.avail_in="<<z.avail_in<<std::endl;
-               bytes_read += is.gcount() - z.avail_in;
-               //dstream<<"bytes_read="<<bytes_read<<std::endl;
 
                if(status == Z_NEED_DICT || status == Z_DATA_ERROR
                                || status == Z_MEM_ERROR)
@@ -168,16 +159,11 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
                        throw SerializationError("decompressZlib: inflate failed");
                }
                int count = output_size - z.avail_out;
-               //dstream<<"count="<<count<<std::endl;
                if(count)
                        os.write(output_buffer, count);
                bytes_written += count;
                if(status == Z_STREAM_END)
                {
-                       //dstream<<"Z_STREAM_END"<<std::endl;
-
-                       //dstream<<"z.avail_in="<<z.avail_in<<std::endl;
-                       //dstream<<"fail="<<is.fail()<<" bad="<<is.bad()<<std::endl;
                        // Unget all the data that inflate didn't take
                        is.clear(); // Just in case EOF is set
                        for(u32 i=0; i < z.avail_in; i++)
@@ -211,9 +197,10 @@ struct ZSTD_Deleter {
 void compressZstd(const u8 *data, size_t data_size, std::ostream &os, int level)
 {
        // reusing the context is recommended for performance
-       // it will destroyed when the thread ends
+       // it will be destroyed when the thread ends
        thread_local std::unique_ptr<ZSTD_CStream, ZSTD_Deleter> stream(ZSTD_createCStream());
 
+
        ZSTD_initCStream(stream.get(), level);
 
        const size_t bufsize = 16384;
@@ -257,7 +244,7 @@ void compressZstd(const std::string &data, std::ostream &os, int level)
 void decompressZstd(std::istream &is, std::ostream &os)
 {
        // reusing the context is recommended for performance
-       // it will destroyed when the thread ends
+       // it will be destroyed when the thread ends
        thread_local std::unique_ptr<ZSTD_DStream, ZSTD_Deleter> stream(ZSTD_createDStream());
 
        ZSTD_initDStream(stream.get());
index 7fb9a78e966b5833237f82e7000fdba191f7f35b..d93f300d287f2152952e3e2252872b849eddd5d9 100644 (file)
@@ -66,6 +66,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "server/player_sao.h"
 #include "server/serverinventorymgr.h"
 #include "translation.h"
+#include "database/database-sqlite3.h"
+#include "database/database-files.h"
+#include "database/database-dummy.h"
+#include "gameparams.h"
 
 class ClientNotFoundException : public BaseException
 {
@@ -250,7 +254,7 @@ Server::Server(
 #if USE_PROMETHEUS
        m_metrics_backend = std::unique_ptr<MetricsBackend>(createPrometheusMetricsBackend());
 #else
-       m_metrics_backend = std::unique_ptr<MetricsBackend>(new MetricsBackend());
+       m_metrics_backend = std::make_unique<MetricsBackend>();
 #endif
 
        m_uptime_counter = m_metrics_backend->addCounter("minetest_core_server_uptime", "Server uptime (in seconds)");
@@ -264,9 +268,15 @@ Server::Server(
                        "minetest_core_latency",
                        "Latency value (in seconds)");
 
-       m_aom_buffer_counter = m_metrics_backend->addCounter(
-                       "minetest_core_aom_generated_count",
-                       "Number of active object messages generated");
+
+       const std::string aom_types[] = {"reliable", "unreliable"};
+       for (u32 i = 0; i < ARRLEN(aom_types); i++) {
+               std::string help_str("Number of active object messages generated (");
+               help_str.append(aom_types[i]).append(")");
+               m_aom_buffer_counter[i] = m_metrics_backend->addCounter(
+                               "minetest_core_aom_generated_count", help_str,
+                               {{"type", aom_types[i]}});
+       }
 
        m_packet_recv_counter = m_metrics_backend->addCounter(
                        "minetest_core_server_packet_recv",
@@ -276,6 +286,10 @@ Server::Server(
                        "minetest_core_server_packet_recv_processed",
                        "Valid received packets processed");
 
+       m_map_edit_event_counter = m_metrics_backend->addCounter(
+                       "minetest_core_map_edit_events",
+                       "Number of map edit events");
+
        m_lag_gauge->set(g_settings->getFloat("dedicated_server_step"));
 }
 
@@ -344,10 +358,15 @@ Server::~Server()
                delete m_thread;
        }
 
+       // Write any changes before deletion.
+       if (m_mod_storage_database)
+               m_mod_storage_database->endSave();
+
        // Delete things in the reverse order of creation
        delete m_emerge;
        delete m_env;
        delete m_rollback;
+       delete m_mod_storage_database;
        delete m_banmanager;
        delete m_itemdef;
        delete m_nodedef;
@@ -387,13 +406,17 @@ void Server::init()
        }
 
        // Create emerge manager
-       m_emerge = new EmergeManager(this);
+       m_emerge = new EmergeManager(this, m_metrics_backend.get());
 
        // Create ban manager
        std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
        m_banmanager = new BanManager(ban_path);
 
-       m_modmgr = std::unique_ptr<ServerModManager>(new ServerModManager(m_path_world));
+       // Create mod storage database and begin a save for later
+       m_mod_storage_database = openModStorageDatabase(m_path_world);
+       m_mod_storage_database->beginSave();
+
+       m_modmgr = std::make_unique<ServerModManager>(m_path_world);
        std::vector<ModSpec> unsatisfied_mods = m_modmgr->getUnsatisfiedMods();
        // complain about mods with unsatisfied dependencies
        if (!m_modmgr->isConsistent()) {
@@ -413,7 +436,7 @@ void Server::init()
        m_script = new ServerScripting(this);
 
        // Must be created before mod loading because we have some inventory creation
-       m_inventory_mgr = std::unique_ptr<ServerInventoryManager>(new ServerInventoryManager());
+       m_inventory_mgr = std::make_unique<ServerInventoryManager>();
 
        m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME);
 
@@ -448,7 +471,8 @@ void Server::init()
 
        // Initialize Environment
        m_startup_server_map = nullptr; // Ownership moved to ServerEnvironment
-       m_env = new ServerEnvironment(servermap, m_script, this, m_path_world);
+       m_env = new ServerEnvironment(servermap, m_script, this,
+               m_path_world, m_metrics_backend.get());
 
        m_inventory_mgr->setEnv(m_env);
        m_clients.setEnv(m_env);
@@ -467,6 +491,9 @@ void Server::init()
        // Give environment reference to scripting api
        m_script->initializeEnvironment(m_env);
 
+       // Do this after regular script init is done
+       m_script->initAsync();
+
        // Register us to receive map edit events
        servermap->addEventReceiver(this);
 
@@ -499,16 +526,17 @@ void Server::start()
 
        // ASCII art for the win!
        std::cerr
-               << "        .__               __                   __   " << std::endl
-               << "  _____ |__| ____   _____/  |_  ____   _______/  |_ " << std::endl
-               << " /     \\|  |/    \\_/ __ \\   __\\/ __ \\ /  ___/\\   __\\" << std::endl
-               << "|  Y Y  \\  |   |  \\  ___/|  | \\  ___/ \\___ \\  |  |  " << std::endl
-               << "|__|_|  /__|___|  /\\___  >__|  \\___  >____  > |__|  " << std::endl
-               << "      \\/        \\/     \\/          \\/     \\/        " << std::endl;
+               << "         __.               __.                 __.  " << std::endl
+               << "  _____ |__| ____   _____ /  |_  _____  _____ /  |_ " << std::endl
+               << " /     \\|  |/    \\ /  __ \\    _\\/  __ \\/   __>    _\\" << std::endl
+               << "|  Y Y  \\  |   |  \\   ___/|  | |   ___/\\___  \\|  |  " << std::endl
+               << "|__|_|  /  |___|  /\\______>  |  \\______>_____/|  |  " << std::endl
+               << "      \\/ \\/     \\/         \\/                  \\/   " << std::endl;
        actionstream << "World at [" << m_path_world << "]" << std::endl;
        actionstream << "Server for gameid=\"" << m_gamespec.id
-                       << "\" listening on " << m_bind_addr.serializeString() << ":"
-                       << m_bind_addr.getPort() << "." << std::endl;
+                       << "\" listening on ";
+       m_bind_addr.print(actionstream);
+       actionstream << "." << std::endl;
 }
 
 void Server::stop()
@@ -517,9 +545,7 @@ void Server::stop()
 
        // Stop threads (set run=false first so both start stopping)
        m_thread->stop();
-       //m_emergethread.setRun(false);
        m_thread->wait();
-       //m_emergethread.stop();
 
        infostream<<"Server: Threads stopped"<<std::endl;
 }
@@ -607,6 +633,7 @@ void Server::AsyncRunStep(bool initial_step)
                        max_lag = dtime;
                }
                m_env->reportMaxLagEstimate(max_lag);
+
                // Step environment
                m_env->step(dtime);
        }
@@ -653,7 +680,7 @@ void Server::AsyncRunStep(bool initial_step)
                ScopeProfiler sp(g_profiler, "Server: liquid transform");
 
                std::map<v3s16, MapBlock*> modified_blocks;
-               m_env->getMap().transformLiquids(modified_blocks, m_env);
+               m_env->getServerMap().transformLiquids(modified_blocks, m_env);
 
                /*
                        Set the modified blocks unsent for all the clients
@@ -711,43 +738,36 @@ void Server::AsyncRunStep(bool initial_step)
                //infostream<<"Server: Checking added and deleted active objects"<<std::endl;
                MutexAutoLock envlock(m_env_mutex);
 
-               m_clients.lock();
-               const RemoteClientMap &clients = m_clients.getClientList();
-               ScopeProfiler sp(g_profiler, "Server: update objects within range");
+               {
+                       ClientInterface::AutoLock clientlock(m_clients);
+                       const RemoteClientMap &clients = m_clients.getClientList();
+                       ScopeProfiler sp(g_profiler, "Server: update objects within range");
 
-               m_player_gauge->set(clients.size());
-               for (const auto &client_it : clients) {
-                       RemoteClient *client = client_it.second;
+                       m_player_gauge->set(clients.size());
+                       for (const auto &client_it : clients) {
+                               RemoteClient *client = client_it.second;
 
-                       if (client->getState() < CS_DefinitionsSent)
-                               continue;
+                               if (client->getState() < CS_DefinitionsSent)
+                                       continue;
 
-                       // This can happen if the client times out somehow
-                       if (!m_env->getPlayer(client->peer_id))
-                               continue;
+                               // This can happen if the client times out somehow
+                               if (!m_env->getPlayer(client->peer_id))
+                                       continue;
 
-                       PlayerSAO *playersao = getPlayerSAO(client->peer_id);
-                       if (!playersao)
-                               continue;
+                               PlayerSAO *playersao = getPlayerSAO(client->peer_id);
+                               if (!playersao)
+                                       continue;
 
-                       SendActiveObjectRemoveAdd(client, playersao);
+                               SendActiveObjectRemoveAdd(client, playersao);
+                       }
                }
-               m_clients.unlock();
 
-               // Save mod storages if modified
+               // Write changes to the mod storage
                m_mod_storage_save_timer -= dtime;
                if (m_mod_storage_save_timer <= 0.0f) {
                        m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
-                       int n = 0;
-                       for (std::unordered_map<std::string, ModMetadata *>::const_iterator
-                               it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
-                               if (it->second->isModified()) {
-                                       it->second->save(getModStoragePath());
-                                       n++;
-                               }
-                       }
-                       if (n > 0)
-                               infostream << "Saved " << n << " modified mod storages." << std::endl;
+                       m_mod_storage_database->endSave();
+                       m_mod_storage_database->beginSave();
                }
        }
 
@@ -764,10 +784,14 @@ void Server::AsyncRunStep(bool initial_step)
 
                // Get active object messages from environment
                ActiveObjectMessage aom(0);
-               u32 aom_count = 0;
+               u32 count_reliable = 0, count_unreliable = 0;
                for(;;) {
                        if (!m_env->getActiveObjectMessage(&aom))
                                break;
+                       if (aom.reliable)
+                               count_reliable++;
+                       else
+                               count_unreliable++;
 
                        std::vector<ActiveObjectMessage>* message_list = nullptr;
                        auto n = buffered_messages.find(aom.id);
@@ -778,68 +802,69 @@ void Server::AsyncRunStep(bool initial_step)
                                message_list = n->second;
                        }
                        message_list->push_back(std::move(aom));
-                       aom_count++;
-               }
-
-               m_aom_buffer_counter->increment(aom_count);
-
-               m_clients.lock();
-               const RemoteClientMap &clients = m_clients.getClientList();
-               // Route data to every client
-               std::string reliable_data, unreliable_data;
-               for (const auto &client_it : clients) {
-                       reliable_data.clear();
-                       unreliable_data.clear();
-                       RemoteClient *client = client_it.second;
-                       PlayerSAO *player = getPlayerSAO(client->peer_id);
-                       // Go through all objects in message buffer
-                       for (const auto &buffered_message : buffered_messages) {
-                               // If object does not exist or is not known by client, skip it
-                               u16 id = buffered_message.first;
-                               ServerActiveObject *sao = m_env->getActiveObject(id);
-                               if (!sao || client->m_known_objects.find(id) == client->m_known_objects.end())
-                                       continue;
+               }
 
-                               // Get message list of object
-                               std::vector<ActiveObjectMessage>* list = buffered_message.second;
-                               // Go through every message
-                               for (const ActiveObjectMessage &aom : *list) {
-                                       // Send position updates to players who do not see the attachment
-                                       if (aom.datastring[0] == AO_CMD_UPDATE_POSITION) {
-                                               if (sao->getId() == player->getId())
-                                                       continue;
-
-                                               // Do not send position updates for attached players
-                                               // as long the parent is known to the client
-                                               ServerActiveObject *parent = sao->getParent();
-                                               if (parent && client->m_known_objects.find(parent->getId()) !=
-                                                               client->m_known_objects.end())
-                                                       continue;
-                                       }
+               m_aom_buffer_counter[0]->increment(count_reliable);
+               m_aom_buffer_counter[1]->increment(count_unreliable);
 
-                                       // Add full new data to appropriate buffer
-                                       std::string &buffer = aom.reliable ? reliable_data : unreliable_data;
-                                       char idbuf[2];
-                                       writeU16((u8*) idbuf, aom.id);
-                                       // u16 id
-                                       // std::string data
-                                       buffer.append(idbuf, sizeof(idbuf));
-                                       buffer.append(serializeString16(aom.datastring));
+               {
+                       ClientInterface::AutoLock clientlock(m_clients);
+                       const RemoteClientMap &clients = m_clients.getClientList();
+                       // Route data to every client
+                       std::string reliable_data, unreliable_data;
+                       for (const auto &client_it : clients) {
+                               reliable_data.clear();
+                               unreliable_data.clear();
+                               RemoteClient *client = client_it.second;
+                               PlayerSAO *player = getPlayerSAO(client->peer_id);
+                               // Go through all objects in message buffer
+                               for (const auto &buffered_message : buffered_messages) {
+                                       // If object does not exist or is not known by client, skip it
+                                       u16 id = buffered_message.first;
+                                       ServerActiveObject *sao = m_env->getActiveObject(id);
+                                       if (!sao || client->m_known_objects.find(id) == client->m_known_objects.end())
+                                               continue;
+
+                                       // Get message list of object
+                                       std::vector<ActiveObjectMessage>* list = buffered_message.second;
+                                       // Go through every message
+                                       for (const ActiveObjectMessage &aom : *list) {
+                                               // Send position updates to players who do not see the attachment
+                                               if (aom.datastring[0] == AO_CMD_UPDATE_POSITION) {
+                                                       if (sao->getId() == player->getId())
+                                                               continue;
+
+                                                       // Do not send position updates for attached players
+                                                       // as long the parent is known to the client
+                                                       ServerActiveObject *parent = sao->getParent();
+                                                       if (parent && client->m_known_objects.find(parent->getId()) !=
+                                                                       client->m_known_objects.end())
+                                                               continue;
+                                               }
+
+                                               // Add full new data to appropriate buffer
+                                               std::string &buffer = aom.reliable ? reliable_data : unreliable_data;
+                                               char idbuf[2];
+                                               writeU16((u8*) idbuf, aom.id);
+                                               // u16 id
+                                               // std::string data
+                                               buffer.append(idbuf, sizeof(idbuf));
+                                               buffer.append(serializeString16(aom.datastring));
+                                       }
+                               }
+                               /*
+                                       reliable_data and unreliable_data are now ready.
+                                       Send them.
+                               */
+                               if (!reliable_data.empty()) {
+                                       SendActiveObjectMessages(client->peer_id, reliable_data);
                                }
-                       }
-                       /*
-                               reliable_data and unreliable_data are now ready.
-                               Send them.
-                       */
-                       if (!reliable_data.empty()) {
-                               SendActiveObjectMessages(client->peer_id, reliable_data);
-                       }
 
-                       if (!unreliable_data.empty()) {
-                               SendActiveObjectMessages(client->peer_id, unreliable_data, false);
+                               if (!unreliable_data.empty()) {
+                                       SendActiveObjectMessages(client->peer_id, unreliable_data, false);
+                               }
                        }
                }
-               m_clients.unlock();
 
                // Clear buffered_messages
                for (auto &buffered_message : buffered_messages) {
@@ -854,15 +879,13 @@ void Server::AsyncRunStep(bool initial_step)
                // We will be accessing the environment
                MutexAutoLock lock(m_env_mutex);
 
-               // Don't send too many at a time
-               //u32 count = 0;
-
-               // Single change sending is disabled if queue size is not small
+               // Single change sending is disabled if queue size is big
                bool disable_single_change_sending = false;
                if(m_unsent_map_edit_queue.size() >= 4)
                        disable_single_change_sending = true;
 
-               int event_count = m_unsent_map_edit_queue.size();
+               const auto event_count = m_unsent_map_edit_queue.size();
+               m_map_edit_event_counter->increment(event_count);
 
                // We'll log the amount of each
                Profiler prof;
@@ -954,14 +977,14 @@ void Server::AsyncRunStep(bool initial_step)
        }
 
        /*
-               Trigger emergethread (it somehow gets to a non-triggered but
-               bysy state sometimes)
+               Trigger emerge thread
+               Doing this every 2s is left over from old code, unclear if this is still needed.
        */
        {
                float &counter = m_emergethread_trigger_timer;
-               counter += dtime;
-               if (counter >= 2.0) {
-                       counter = 0.0;
+               counter -= dtime;
+               if (counter <= 0.0f) {
+                       counter = 2.0f;
 
                        m_emerge->startThreads();
                }
@@ -1032,8 +1055,7 @@ void Server::Receive()
                } catch (const ClientStateError &e) {
                        errorstream << "ProcessData: peer=" << peer_id << " what()="
                                         << e.what() << std::endl;
-                       DenyAccess_Legacy(peer_id, L"Your client sent something server didn't expect."
-                                       L"Try reconnecting or updating your client");
+                       DenyAccess(peer_id, SERVER_ACCESSDENIED_UNEXPECTED_DATA);
                } catch (const con::PeerNotFoundException &e) {
                        // Do nothing
                } catch (const con::NoIncomingDataException &e) {
@@ -1046,18 +1068,14 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
 {
        std::string playername;
        PlayerSAO *playersao = NULL;
-       m_clients.lock();
-       try {
+       {
+               ClientInterface::AutoLock clientlock(m_clients);
                RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
                if (client) {
                        playername = client->getName();
                        playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version);
                }
-       } catch (std::exception &e) {
-               m_clients.unlock();
-               throw;
        }
-       m_clients.unlock();
 
        RemotePlayer *player = m_env->getPlayer(playername.c_str());
 
@@ -1066,15 +1084,13 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
                if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
                        actionstream << "Server: Failed to emerge player \"" << playername
                                        << "\" (player allocated to an another client)" << std::endl;
-                       DenyAccess_Legacy(peer_id, L"Another client is connected with this "
-                                       L"name. If your client closed unexpectedly, try again in "
-                                       L"a minute.");
+                       DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED);
                } else {
                        errorstream << "Server: " << playername << ": Failed to emerge player"
                                        << std::endl;
-                       DenyAccess_Legacy(peer_id, L"Could not allocate player.");
+                       DenyAccess(peer_id, SERVER_ACCESSDENIED_SERVER_FAIL);
                }
-               return NULL;
+               return nullptr;
        }
 
        /*
@@ -1091,30 +1107,32 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
        // Send inventory
        SendInventory(playersao, false);
 
-       // Send HP or death screen
+       // Send HP
+       SendPlayerHP(playersao);
+
+       // Send death screen
        if (playersao->isDead())
                SendDeathscreen(peer_id, false, v3f(0,0,0));
-       else
-               SendPlayerHP(peer_id);
 
        // Send Breath
        SendPlayerBreath(playersao);
 
        /*
-               Print out action
+               Update player list and print action
        */
        {
-               Address addr = getPeerAddress(player->getPeerId());
-               std::string ip_str = addr.serializeString();
-               const std::vector<std::string> &names = m_clients.getPlayerNames();
+               NetworkPacket notice_pkt(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
+               notice_pkt << (u8) PLAYER_LIST_ADD << (u16) 1 << std::string(player->getName());
+               m_clients.sendToAll(&notice_pkt);
+       }
+       {
+               std::string ip_str = getPeerAddress(player->getPeerId()).serializeString();
+               const auto &names = m_clients.getPlayerNames();
 
                actionstream << player->getName() << " [" << ip_str << "] joins game. List of players: ";
-
-               for (const std::string &name : names) {
+               for (const std::string &name : names)
                        actionstream << name << " ";
-               }
-
-               actionstream << player->getName() <<std::endl;
+               actionstream << player->getName() << std::endl;
        }
        return playersao;
 }
@@ -1137,18 +1155,16 @@ void Server::ProcessData(NetworkPacket *pkt)
                Address address = getPeerAddress(peer_id);
                std::string addr_s = address.serializeString();
 
-               if(m_banmanager->isIpBanned(addr_s)) {
+               // FIXME: Isn't it a bit excessive to check this for every packet?
+               if (m_banmanager->isIpBanned(addr_s)) {
                        std::string ban_name = m_banmanager->getBanName(addr_s);
                        infostream << "Server: A banned client tried to connect from "
-                                       << addr_s << "; banned name was "
-                                       << ban_name << std::endl;
-                       // This actually doesn't seem to transfer to the client
-                       DenyAccess_Legacy(peer_id, L"Your ip is banned. Banned name was "
-                                       + utf8_to_wide(ban_name));
+                                       << addr_s << "; banned name was " << ban_name << std::endl;
+                       DenyAccess(peer_id, SERVER_ACCESSDENIED_CUSTOM_STRING,
+                               "Your IP is banned. Banned name was " + ban_name);
                        return;
                }
-       }
-       catch(con::PeerNotFoundException &e) {
+       } catch (con::PeerNotFoundException &e) {
                /*
                 * no peer for this packet found
                 * most common reason is peer timeout, e.g. peer didn't
@@ -1228,13 +1244,12 @@ void Server::onMapEditEvent(const MapEditEvent &event)
 void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block)
 {
        std::vector<session_t> clients = m_clients.getClientIDs();
-       m_clients.lock();
+       ClientInterface::AutoLock clientlock(m_clients);
        // Set the modified blocks unsent for all the clients
        for (const session_t client_id : clients) {
                        if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id))
                                client->SetBlocksNotSent(block);
        }
-       m_clients.unlock();
 }
 
 void Server::peerAdded(con::Peer *peer)
@@ -1262,13 +1277,11 @@ bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float*
 
 bool Server::getClientInfo(session_t peer_id, ClientInfo &ret)
 {
-       m_clients.lock();
+       ClientInterface::AutoLock clientlock(m_clients);
        RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
 
-       if (!client) {
-               m_clients.unlock();
+       if (!client)
                return false;
-       }
 
        ret.state = client->getState();
        ret.addr = client->getAddress();
@@ -1283,8 +1296,6 @@ bool Server::getClientInfo(session_t peer_id, ClientInfo &ret)
 
        ret.lang_code = client->getLangCode();
 
-       m_clients.unlock();
-
        return true;
 }
 
@@ -1361,18 +1372,21 @@ void Server::SendMovement(session_t peer_id)
        Send(&pkt);
 }
 
-void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
+void Server::HandlePlayerHPChange(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
 {
-       if (playersao->isImmortal())
-               return;
+       m_script->player_event(playersao, "health_changed");
+       SendPlayerHP(playersao);
 
-       session_t peer_id = playersao->getPeerID();
-       bool is_alive = !playersao->isDead();
+       // Send to other clients
+       playersao->sendPunchCommand();
 
-       if (is_alive)
-               SendPlayerHP(peer_id);
-       else
-               DiePlayer(peer_id, reason);
+       if (playersao->isDead())
+               HandlePlayerDeath(playersao, reason);
+}
+
+void Server::SendPlayerHP(PlayerSAO *playersao)
+{
+       SendHP(playersao->getPeerID(), playersao->getHP());
 }
 
 void Server::SendHP(session_t peer_id, u16 hp)
@@ -1404,13 +1418,6 @@ void Server::SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
        Send(&pkt);
 }
 
-void Server::SendAccessDenied_Legacy(session_t peer_id,const std::wstring &reason)
-{
-       NetworkPacket pkt(TOCLIENT_ACCESS_DENIED_LEGACY, 0, peer_id);
-       pkt << reason;
-       Send(&pkt);
-}
-
 void Server::SendDeathscreen(session_t peer_id, bool set_camera_point_target,
                v3f camera_point_target)
 {
@@ -1793,6 +1800,16 @@ void Server::SendOverrideDayNightRatio(session_t peer_id, bool do_override,
        Send(&pkt);
 }
 
+void Server::SendSetLighting(session_t peer_id, const Lighting &lighting)
+{
+       NetworkPacket pkt(TOCLIENT_SET_LIGHTING,
+                       4, peer_id);
+       
+       pkt << lighting.shadow_intensity;
+
+       Send(&pkt);
+}
+
 void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
 {
        NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
@@ -1806,18 +1823,6 @@ void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
        }
 }
 
-void Server::SendPlayerHP(session_t peer_id)
-{
-       PlayerSAO *playersao = getPlayerSAO(peer_id);
-       assert(playersao);
-
-       SendHP(peer_id, playersao->getHP());
-       m_script->player_event(playersao,"health_changed");
-
-       // Send to other clients
-       playersao->sendPunchCommand();
-}
-
 void Server::SendPlayerBreath(PlayerSAO *sao)
 {
        assert(sao);
@@ -2222,7 +2227,7 @@ void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
        pkt << p;
 
        std::vector<session_t> clients = m_clients.getClientIDs();
-       m_clients.lock();
+       ClientInterface::AutoLock clientlock(m_clients);
 
        for (session_t client_id : clients) {
                RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
@@ -2245,8 +2250,6 @@ void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
                // Send as reliable
                m_clients.send(client_id, 0, &pkt, true);
        }
-
-       m_clients.unlock();
 }
 
 void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
@@ -2261,7 +2264,7 @@ void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_player
                        << (u8) (remove_metadata ? 0 : 1);
 
        std::vector<session_t> clients = m_clients.getClientIDs();
-       m_clients.lock();
+       ClientInterface::AutoLock clientlock(m_clients);
 
        for (session_t client_id : clients) {
                RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
@@ -2284,8 +2287,6 @@ void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_player
                // Send as reliable
                m_clients.send(client_id, 0, &pkt, true);
        }
-
-       m_clients.unlock();
 }
 
 void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far_d_nodes)
@@ -2294,7 +2295,7 @@ void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far
        NodeMetadataList meta_updates_list(false);
        std::vector<session_t> clients = m_clients.getClientIDs();
 
-       m_clients.lock();
+       ClientInterface::AutoLock clientlock(m_clients);
 
        for (session_t i : clients) {
                RemoteClient *client = m_clients.lockedGetClientNoEx(i);
@@ -2335,27 +2336,37 @@ void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far
 
                meta_updates_list.clear();
        }
-
-       m_clients.unlock();
 }
 
 void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
-               u16 net_proto_version)
+               u16 net_proto_version, SerializedBlockCache *cache)
 {
-       /*
-               Create a packet with the block in the right format
-       */
        thread_local const int net_compression_level = rangelim(g_settings->getS16("map_compression_level_net"), -1, 9);
-       std::ostringstream os(std::ios_base::binary);
-       block->serialize(os, ver, false, net_compression_level);
-       block->serializeNetworkSpecific(os);
-       std::string s = os.str();
+       std::string s, *sptr = nullptr;
 
-       NetworkPacket pkt(TOCLIENT_BLOCKDATA, 2 + 2 + 2 + s.size(), peer_id);
+       if (cache) {
+               auto it = cache->find({block->getPos(), ver});
+               if (it != cache->end())
+                       sptr = &it->second;
+       }
+
+       // Serialize the block in the right format
+       if (!sptr) {
+               std::ostringstream os(std::ios_base::binary);
+               block->serialize(os, ver, false, net_compression_level);
+               block->serializeNetworkSpecific(os);
+               s = os.str();
+               sptr = &s;
+       }
 
+       NetworkPacket pkt(TOCLIENT_BLOCKDATA, 2 + 2 + 2 + sptr->size(), peer_id);
        pkt << block->getPos();
-       pkt.putRawString(s.c_str(), s.size());
+       pkt.putRawString(*sptr);
        Send(&pkt);
+
+       // Store away in cache
+       if (cache && sptr == &s)
+               (*cache)[{block->getPos(), ver}] = std::move(s);
 }
 
 void Server::SendBlocks(float dtime)
@@ -2365,14 +2376,14 @@ void Server::SendBlocks(float dtime)
 
        std::vector<PrioritySortedBlockTransfer> queue;
 
-       u32 total_sending = 0;
+       u32 total_sending = 0, unique_clients = 0;
 
        {
                ScopeProfiler sp2(g_profiler, "Server::SendBlocks(): Collect list");
 
                std::vector<session_t> clients = m_clients.getClientIDs();
 
-               m_clients.lock();
+               ClientInterface::AutoLock clientlock(m_clients);
                for (const session_t client_id : clients) {
                        RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active);
 
@@ -2380,9 +2391,10 @@ void Server::SendBlocks(float dtime)
                                continue;
 
                        total_sending += client->getSendingCount();
+                       const auto old_count = queue.size();
                        client->GetNextBlocks(m_env,m_emerge, dtime, queue);
+                       unique_clients += queue.size() > old_count ? 1 : 0;
                }
-               m_clients.unlock();
        }
 
        // Sort.
@@ -2390,7 +2402,7 @@ void Server::SendBlocks(float dtime)
        // Lowest is most important.
        std::sort(queue.begin(), queue.end());
 
-       m_clients.lock();
+       ClientInterface::AutoLock clientlock(m_clients);
 
        // Maximal total count calculation
        // The per-client block sends is halved with the maximal online users
@@ -2400,6 +2412,12 @@ void Server::SendBlocks(float dtime)
        ScopeProfiler sp(g_profiler, "Server::SendBlocks(): Send to clients");
        Map &map = m_env->getMap();
 
+       SerializedBlockCache cache, *cache_ptr = nullptr;
+       if (unique_clients > 1) {
+               // caching is pointless with a single client
+               cache_ptr = &cache;
+       }
+
        for (const PrioritySortedBlockTransfer &block_to_send : queue) {
                if (total_sending >= max_blocks_to_send)
                        break;
@@ -2414,12 +2432,11 @@ void Server::SendBlocks(float dtime)
                        continue;
 
                SendBlockNoLock(block_to_send.peer_id, block, client->serialization_version,
-                               client->net_proto_version);
+                               client->net_proto_version, cache_ptr);
 
                client->SentBlock(block_to_send.pos);
                total_sending++;
        }
-       m_clients.unlock();
 }
 
 bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos)
@@ -2428,15 +2445,12 @@ bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos)
        if (!block)
                return false;
 
-       m_clients.lock();
+       ClientInterface::AutoLock clientlock(m_clients);
        RemoteClient *client = m_clients.lockedGetClientNoEx(peer_id, CS_Active);
-       if (!client || client->isBlockSent(blockpos)) {
-               m_clients.unlock();
+       if (!client || client->isBlockSent(blockpos))
                return false;
-       }
        SendBlockNoLock(peer_id, block, client->serialization_version,
                        client->net_proto_version);
-       m_clients.unlock();
 
        return true;
 }
@@ -2746,23 +2760,18 @@ void Server::sendDetachedInventories(session_t peer_id, bool incremental)
        Something random
 */
 
-void Server::DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason)
+void Server::HandlePlayerDeath(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
 {
-       PlayerSAO *playersao = getPlayerSAO(peer_id);
-       assert(playersao);
-
        infostream << "Server::DiePlayer(): Player "
                        << playersao->getPlayer()->getName()
                        << " dies" << std::endl;
 
-       playersao->setHP(0, reason);
        playersao->clearParentAttachment();
 
        // Trigger scripted stuff
        m_script->on_dieplayer(playersao, reason);
 
-       SendPlayerHP(peer_id);
-       SendDeathscreen(peer_id, false, v3f(0,0,0));
+       SendDeathscreen(playersao->getPeerID(), false, v3f(0,0,0));
 }
 
 void Server::RespawnPlayer(session_t peer_id)
@@ -2783,8 +2792,6 @@ void Server::RespawnPlayer(session_t peer_id)
                // setPos will send the new position to client
                playersao->setPos(findSpawnPos());
        }
-
-       SendPlayerHP(peer_id);
 }
 
 
@@ -2795,29 +2802,10 @@ void Server::DenySudoAccess(session_t peer_id)
 }
 
 
-void Server::DenyAccessVerCompliant(session_t peer_id, u16 proto_ver, AccessDeniedCode reason,
-               const std::string &str_reason, bool reconnect)
-{
-       SendAccessDenied(peer_id, reason, str_reason, reconnect);
-
-       m_clients.event(peer_id, CSE_SetDenied);
-       DisconnectPeer(peer_id);
-}
-
-
 void Server::DenyAccess(session_t peer_id, AccessDeniedCode reason,
-               const std::string &custom_reason)
-{
-       SendAccessDenied(peer_id, reason, custom_reason);
-       m_clients.event(peer_id, CSE_SetDenied);
-       DisconnectPeer(peer_id);
-}
-
-// 13/03/15: remove this function when protocol version 25 will become
-// the minimum version for MT users, maybe in 1 year
-void Server::DenyAccess_Legacy(session_t peer_id, const std::wstring &reason)
+               const std::string &custom_reason, bool reconnect)
 {
-       SendAccessDenied_Legacy(peer_id, reason);
+       SendAccessDenied(peer_id, reason, custom_reason, reconnect);
        m_clients.event(peer_id, CSE_SetDenied);
        DisconnectPeer(peer_id);
 }
@@ -3003,8 +2991,8 @@ std::wstring Server::handleChat(const std::string &name,
                        return ws.str();
                }
                case RPLAYER_CHATRESULT_KICK:
-                       DenyAccess_Legacy(player->getPeerId(),
-                                       L"You have been kicked due to message flooding.");
+                       DenyAccess(player->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING,
+                               "You have been kicked due to message flooding.");
                        return L"";
                case RPLAYER_CHATRESULT_OK:
                        break;
@@ -3119,15 +3107,18 @@ std::string Server::getStatusString()
        std::ostringstream os(std::ios_base::binary);
        os << "# Server: ";
        // Version
-       os << "version=" << g_version_string;
+       os << "version: " << g_version_string;
+       // Game
+       os << " | game: " << (m_gamespec.name.empty() ? m_gamespec.id : m_gamespec.name);
        // Uptime
-       os << ", uptime=" << m_uptime_counter->get();
+       os << " | uptime: " << duration_to_string((int) m_uptime_counter->get());
        // Max lag estimate
-       os << ", max_lag=" << (m_env ? m_env->getMaxLagEstimate() : 0);
+       os << " | max lag: " << std::setprecision(3);
+       os << (m_env ? m_env->getMaxLagEstimate() : 0) << "s";
 
        // Information about clients
        bool first = true;
-       os << ", clients={";
+       os << " | clients: ";
        if (m_env) {
                std::vector<session_t> clients = m_clients.getClientIDs();
                for (session_t client_id : clients) {
@@ -3144,7 +3135,6 @@ std::string Server::getStatusString()
                        os << name;
                }
        }
-       os << "}";
 
        if (m_env && !((ServerMap*)(&m_env->getMap()))->isSavingEnabled())
                os << std::endl << "# Server: " << " WARNING: Map saving is disabled.";
@@ -3298,9 +3288,12 @@ bool Server::hudSetFlags(RemotePlayer *player, u32 flags, u32 mask)
        if (!player)
                return false;
 
+       u32 new_hud_flags = (player->hud_flags & ~mask) | flags;
+       if (new_hud_flags == player->hud_flags) // no change
+               return true;
+       
        SendHUDSetFlags(player->getPeerId(), flags, mask);
-       player->hud_flags &= ~mask;
-       player->hud_flags |= flags;
+       player->hud_flags = new_hud_flags;
 
        PlayerSAO* playersao = player->getPlayerSAO();
 
@@ -3409,6 +3402,13 @@ void Server::overrideDayNightRatio(RemotePlayer *player, bool do_override,
        SendOverrideDayNightRatio(player->getPeerId(), do_override, ratio);
 }
 
+void Server::setLighting(RemotePlayer *player, const Lighting &lighting)
+{
+       sanity_check(player);
+       player->setLighting(lighting);
+       SendSetLighting(player->getPeerId(), lighting);
+}
+
 void Server::notifyPlayers(const std::wstring &msg)
 {
        SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
@@ -3543,34 +3543,49 @@ bool Server::dynamicAddMedia(std::string filepath,
        legacy_pkt.putLongString(filedata);
 
        std::unordered_set<session_t> delivered, waiting;
-       m_clients.lock();
-       for (auto &pair : m_clients.getClientList()) {
-               if (pair.second->getState() < CS_DefinitionsSent)
-                       continue;
-               const auto proto_ver = pair.second->net_proto_version;
-               if (proto_ver < 39)
-                       continue;
+       {
+               ClientInterface::AutoLock clientlock(m_clients);
+               for (auto &pair : m_clients.getClientList()) {
+                       if (pair.second->getState() == CS_DefinitionsSent && !ephemeral) {
+                               /*
+                                       If a client is in the DefinitionsSent state it is too late to
+                                       transfer the file via sendMediaAnnouncement() but at the same
+                                       time the client cannot accept a media push yet.
+                                       Short of artificially delaying the joining process there is no
+                                       way for the server to resolve this so we (currently) opt not to.
+                               */
+                               warningstream << "The media \"" << filename << "\" (dynamic) could "
+                                       "not be delivered to " << pair.second->getName()
+                                       << " due to a race condition." << std::endl;
+                               continue;
+                       }
+                       if (pair.second->getState() < CS_Active)
+                               continue;
 
-               const session_t peer_id = pair.second->peer_id;
-               if (!to_player.empty() && getPlayerName(peer_id) != to_player)
-                       continue;
+                       const auto proto_ver = pair.second->net_proto_version;
+                       if (proto_ver < 39)
+                               continue;
 
-               if (proto_ver < 40) {
-                       delivered.emplace(peer_id);
-                       /*
-                               The network layer only guarantees ordered delivery inside a channel.
-                               Since the very next packet could be one that uses the media, we have
-                               to push the media over ALL channels to ensure it is processed before
-                               it is used. In practice this means channels 1 and 0.
-                       */
-                       m_clients.send(peer_id, 1, &legacy_pkt, true);
-                       m_clients.send(peer_id, 0, &legacy_pkt, true);
-               } else {
-                       waiting.emplace(peer_id);
-                       Send(peer_id, &pkt);
+                       const session_t peer_id = pair.second->peer_id;
+                       if (!to_player.empty() && getPlayerName(peer_id) != to_player)
+                               continue;
+
+                       if (proto_ver < 40) {
+                               delivered.emplace(peer_id);
+                               /*
+                                       The network layer only guarantees ordered delivery inside a channel.
+                                       Since the very next packet could be one that uses the media, we have
+                                       to push the media over ALL channels to ensure it is processed before
+                                       it is used. In practice this means channels 1 and 0.
+                               */
+                               m_clients.send(peer_id, 1, &legacy_pkt, true);
+                               m_clients.send(peer_id, 0, &legacy_pkt, true);
+                       } else {
+                               waiting.emplace(peer_id);
+                               Send(peer_id, &pkt);
+                       }
                }
        }
-       m_clients.unlock();
 
        // Run callback for players that already had the file delivered (legacy-only)
        for (session_t peer_id : delivered) {
@@ -3680,21 +3695,11 @@ const ModSpec *Server::getModSpec(const std::string &modname) const
        return m_modmgr->getModSpec(modname);
 }
 
-void Server::getModNames(std::vector<std::string> &modlist)
-{
-       m_modmgr->getModNames(modlist);
-}
-
 std::string Server::getBuiltinLuaPath()
 {
        return porting::path_share + DIR_DELIM + "builtin";
 }
 
-std::string Server::getModStoragePath() const
-{
-       return m_path_world + DIR_DELIM + "mod_storage";
-}
-
 v3f Server::findSpawnPos()
 {
        ServerMap &map = m_env->getServerMap();
@@ -3858,11 +3863,8 @@ bool Server::registerModStorage(ModMetadata *storage)
 void Server::unregisterModStorage(const std::string &name)
 {
        std::unordered_map<std::string, ModMetadata *>::const_iterator it = m_mod_storages.find(name);
-       if (it != m_mod_storages.end()) {
-               // Save unconditionaly on unregistration
-               it->second->save(getModStoragePath());
+       if (it != m_mod_storages.end())
                m_mod_storages.erase(name);
-       }
 }
 
 void dedicated_server_loop(Server &server, bool &kill)
@@ -4000,3 +4002,106 @@ Translations *Server::getTranslationLanguage(const std::string &lang_code)
 
        return translations;
 }
+
+ModMetadataDatabase *Server::openModStorageDatabase(const std::string &world_path)
+{
+       std::string world_mt_path = world_path + DIR_DELIM + "world.mt";
+       Settings world_mt;
+       if (!world_mt.readConfigFile(world_mt_path.c_str()))
+               throw BaseException("Cannot read world.mt!");
+
+       std::string backend = world_mt.exists("mod_storage_backend") ?
+               world_mt.get("mod_storage_backend") : "files";
+       if (backend == "files")
+               warningstream << "/!\\ You are using the old mod storage files backend. "
+                       << "This backend is deprecated and may be removed in a future release /!\\"
+                       << std::endl << "Switching to SQLite3 is advised, "
+                       << "please read http://wiki.minetest.net/Database_backends." << std::endl;
+
+       return openModStorageDatabase(backend, world_path, world_mt);
+}
+
+ModMetadataDatabase *Server::openModStorageDatabase(const std::string &backend,
+               const std::string &world_path, const Settings &world_mt)
+{
+       if (backend == "sqlite3")
+               return new ModMetadataDatabaseSQLite3(world_path);
+
+       if (backend == "files")
+               return new ModMetadataDatabaseFiles(world_path);
+
+       if (backend == "dummy")
+               return new Database_Dummy();
+
+       throw BaseException("Mod storage database backend " + backend + " not supported");
+}
+
+bool Server::migrateModStorageDatabase(const GameParams &game_params, const Settings &cmd_args)
+{
+       std::string migrate_to = cmd_args.get("migrate-mod-storage");
+       Settings world_mt;
+       std::string world_mt_path = game_params.world_path + DIR_DELIM + "world.mt";
+       if (!world_mt.readConfigFile(world_mt_path.c_str())) {
+               errorstream << "Cannot read world.mt!" << std::endl;
+               return false;
+       }
+
+       std::string backend = world_mt.exists("mod_storage_backend") ?
+               world_mt.get("mod_storage_backend") : "files";
+       if (backend == migrate_to) {
+               errorstream << "Cannot migrate: new backend is same"
+                       << " as the old one" << std::endl;
+               return false;
+       }
+
+       ModMetadataDatabase *srcdb = nullptr;
+       ModMetadataDatabase *dstdb = nullptr;
+
+       bool succeeded = false;
+
+       try {
+               srcdb = Server::openModStorageDatabase(backend, game_params.world_path, world_mt);
+               dstdb = Server::openModStorageDatabase(migrate_to, game_params.world_path, world_mt);
+
+               dstdb->beginSave();
+
+               std::vector<std::string> mod_list;
+               srcdb->listMods(&mod_list);
+               for (const std::string &modname : mod_list) {
+                       StringMap meta;
+                       srcdb->getModEntries(modname, &meta);
+                       for (const auto &pair : meta) {
+                               dstdb->setModEntry(modname, pair.first, pair.second);
+                       }
+               }
+
+               dstdb->endSave();
+
+               succeeded = true;
+
+               actionstream << "Successfully migrated the metadata of "
+                       << mod_list.size() << " mods" << std::endl;
+               world_mt.set("mod_storage_backend", migrate_to);
+               if (!world_mt.updateConfigFile(world_mt_path.c_str()))
+                       errorstream << "Failed to update world.mt!" << std::endl;
+               else
+                       actionstream << "world.mt updated" << std::endl;
+
+       } catch (BaseException &e) {
+               errorstream << "An error occurred during migration: " << e.what() << std::endl;
+       }
+
+       delete srcdb;
+       delete dstdb;
+
+       if (succeeded && backend == "files") {
+               // Back up files
+               const std::string storage_path = game_params.world_path + DIR_DELIM + "mod_storage";
+               const std::string backup_path = game_params.world_path + DIR_DELIM + "mod_storage.bak";
+               if (!fs::Rename(storage_path, backup_path))
+                       warningstream << "After migration, " << storage_path
+                               << " could not be renamed to " << backup_path << std::endl;
+       }
+
+       return succeeded;
+}
index c5db0fdfb49427b5ea2a3d75c56d2f35f2ae3ddf..2c21f5dfc899c5a812b39a1a9f28f96ea4e06773 100644 (file)
@@ -69,9 +69,11 @@ struct SkyboxParams;
 struct SunParams;
 struct MoonParams;
 struct StarParams;
+struct Lighting;
 class ServerThread;
 class ServerModManager;
 class ServerInventoryManager;
+struct PackedValue;
 
 enum ClientDeletionReason {
        CDR_LEAVE,
@@ -283,6 +285,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
        virtual u16 allocateUnknownNodeId(const std::string &name);
        IRollbackManager *getRollbackManager() { return m_rollback; }
        virtual EmergeManager *getEmergeManager() { return m_emerge; }
+       virtual ModMetadataDatabase *getModStorageDatabase() { return m_mod_storage_database; }
 
        IWritableItemDefManager* getWritableItemDefManager();
        NodeDefManager* getWritableNodeDefManager();
@@ -290,12 +293,10 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 
        virtual const std::vector<ModSpec> &getMods() const;
        virtual const ModSpec* getModSpec(const std::string &modname) const;
-       void getModNames(std::vector<std::string> &modlist);
-       std::string getBuiltinLuaPath();
+       static std::string getBuiltinLuaPath();
        virtual std::string getWorldPath() const { return m_path_world; }
-       virtual std::string getModStoragePath() const;
 
-       inline bool isSingleplayer()
+       inline bool isSingleplayer() const
                        { return m_simple_singleplayer_mode; }
 
        inline void setAsyncFatalError(const std::string &error)
@@ -333,24 +334,24 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 
        void overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness);
 
+       void setLighting(RemotePlayer *player, const Lighting &lighting);
+
        /* con::PeerHandler implementation. */
        void peerAdded(con::Peer *peer);
        void deletingPeer(con::Peer *peer, bool timeout);
 
        void DenySudoAccess(session_t peer_id);
-       void DenyAccessVerCompliant(session_t peer_id, u16 proto_ver, AccessDeniedCode reason,
-               const std::string &str_reason = "", bool reconnect = false);
        void DenyAccess(session_t peer_id, AccessDeniedCode reason,
-               const std::string &custom_reason = "");
+               const std::string &custom_reason = "", bool reconnect = false);
        void acceptAuth(session_t peer_id, bool forSudoMode);
-       void DenyAccess_Legacy(session_t peer_id, const std::wstring &reason);
        void DisconnectPeer(session_t peer_id);
        bool getClientConInfo(session_t peer_id, con::rtt_stat_type type, float *retval);
        bool getClientInfo(session_t peer_id, ClientInfo &ret);
 
        void printToConsoleOnly(const std::string &text);
 
-       void SendPlayerHPOrDie(PlayerSAO *player, const PlayerHPChangeReason &reason);
+       void HandlePlayerHPChange(PlayerSAO *sao, const PlayerHPChangeReason &reason);
+       void SendPlayerHP(PlayerSAO *sao);
        void SendPlayerBreath(PlayerSAO *sao);
        void SendInventory(PlayerSAO *playerSAO, bool incremental);
        void SendMovePlayer(session_t peer_id);
@@ -377,6 +378,20 @@ class Server : public con::PeerHandler, public MapEventReceiver,
        // Get or load translations for a language
        Translations *getTranslationLanguage(const std::string &lang_code);
 
+       static ModMetadataDatabase *openModStorageDatabase(const std::string &world_path);
+
+       static ModMetadataDatabase *openModStorageDatabase(const std::string &backend,
+                       const std::string &world_path, const Settings &world_mt);
+
+       static bool migrateModStorageDatabase(const GameParams &game_params,
+                       const Settings &cmd_args);
+
+       // Lua files registered for init of async env, pair of modname + path
+       std::vector<std::pair<std::string, std::string>> m_async_init_files;
+
+       // Data transferred into async envs at init time
+       std::unique_ptr<PackedValue> m_async_globals_data;
+
        // Bind address
        Address m_bind_addr;
 
@@ -410,6 +425,16 @@ class Server : public con::PeerHandler, public MapEventReceiver,
                std::unordered_set<session_t> waiting_players;
        };
 
+       // the standard library does not implement std::hash for pairs so we have this:
+       struct SBCHash {
+               size_t operator() (const std::pair<v3s16, u16> &p) const {
+                       return (((size_t) p.first.X) << 48) | (((size_t) p.first.Y) << 32) |
+                               (((size_t) p.first.Z) << 16) | ((size_t) p.second);
+               }
+       };
+
+       typedef std::unordered_map<std::pair<v3s16, u16>, std::string, SBCHash> SerializedBlockCache;
+
        void init();
 
        void SendMovement(session_t peer_id);
@@ -430,7 +455,6 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 
        virtual void SendChatMessage(session_t peer_id, const ChatMessage &message);
        void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed);
-       void SendPlayerHP(session_t peer_id);
 
        void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4],
                f32 animation_speed);
@@ -451,6 +475,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
        void SendSetStars(session_t peer_id, const StarParams &params);
        void SendCloudParams(session_t peer_id, const CloudParams &params);
        void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
+       void SendSetLighting(session_t peer_id, const Lighting &lighting);
        void broadcastModChannelMessage(const std::string &channel,
                        const std::string &message, session_t from_peer);
 
@@ -470,7 +495,9 @@ class Server : public con::PeerHandler, public MapEventReceiver,
                        float far_d_nodes = 100);
 
        // Environment and Connection must be locked when called
-       void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, u16 net_proto_version);
+       // `cache` may only be very short lived! (invalidation not handeled)
+       void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
+               u16 net_proto_version, SerializedBlockCache *cache = nullptr);
 
        // Sends blocks to clients (locks env and con on its own)
        void SendBlocks(float dtime);
@@ -502,7 +529,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
                Something random
        */
 
-       void DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason);
+       void HandlePlayerDeath(PlayerSAO* sao, const PlayerHPChangeReason &reason);
        void RespawnPlayer(session_t peer_id);
        void DeleteClient(session_t peer_id, ClientDeletionReason reason);
        void UpdateCrafting(RemotePlayer *player);
@@ -678,6 +705,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
        s32 nextSoundId();
 
        std::unordered_map<std::string, ModMetadata *> m_mod_storages;
+       ModMetadataDatabase *m_mod_storage_database = nullptr;
        float m_mod_storage_save_timer = 10.0f;
 
        // CSM restrictions byteflag
@@ -697,11 +725,11 @@ class Server : public con::PeerHandler, public MapEventReceiver,
        MetricCounterPtr m_uptime_counter;
        MetricGaugePtr m_player_gauge;
        MetricGaugePtr m_timeofday_gauge;
-       // current server step lag
        MetricGaugePtr m_lag_gauge;
-       MetricCounterPtr m_aom_buffer_counter;
+       MetricCounterPtr m_aom_buffer_counter[2]; // [0] = rel, [1] = unrel
        MetricCounterPtr m_packet_recv_counter;
        MetricCounterPtr m_packet_recv_processed_counter;
+       MetricCounterPtr m_map_edit_event_counter;
 };
 
 /*
index 3bcbe107b39beb7602a6175b1432bb0397d9f97f..82f6da2314f8392d66b924844f53d3d6a3a385c2 100644 (file)
@@ -108,7 +108,12 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
                m_env->getScriptIface()->
                        luaentity_Activate(m_id, m_init_state, dtime_s);
        } else {
+               // It's an unknown object
+               // Use entitystring as infotext for debugging
                m_prop.infotext = m_init_name;
+               // Set unknown object texture
+               m_prop.textures.clear();
+               m_prop.textures.emplace_back("unknown_object.png");
        }
 }
 
@@ -300,10 +305,11 @@ void LuaEntitySAO::getStaticData(std::string *result) const
        *result = os.str();
 }
 
-u16 LuaEntitySAO::punch(v3f dir,
+u32 LuaEntitySAO::punch(v3f dir,
                const ToolCapabilities *toolcap,
                ServerActiveObject *puncher,
-               float time_from_last_punch)
+               float time_from_last_punch,
+               u16 initial_wear)
 {
        if (!m_registered) {
                // Delete unknown LuaEntities when punched
@@ -321,7 +327,8 @@ u16 LuaEntitySAO::punch(v3f dir,
                        m_armor_groups,
                        toolcap,
                        &tool_item,
-                       time_from_last_punch);
+                       time_from_last_punch,
+                       initial_wear);
 
        bool damage_handled = m_env->getScriptIface()->luaentity_Punch(m_id, puncher,
                        time_from_last_punch, toolcap, dir, result.did_punch ? result.damage : 0);
index 6883ae1b9ad3c3eb35eccaf43ed55622b30fd2a6..87b664a8b282708acaaf717581f26df2d8b758e6 100644 (file)
@@ -44,9 +44,10 @@ class LuaEntitySAO : public UnitSAO
        bool isStaticAllowed() const { return m_prop.static_save; }
        bool shouldUnload() const { return true; }
        void getStaticData(std::string *result) const;
-       u16 punch(v3f dir, const ToolCapabilities *toolcap = nullptr,
+       u32 punch(v3f dir, const ToolCapabilities *toolcap = nullptr,
                        ServerActiveObject *puncher = nullptr,
-                       float time_from_last_punch = 1000000.0f);
+                       float time_from_last_punch = 1000000.0f,
+                       u16 initial_wear = 0);
        void rightClick(ServerActiveObject *clicker);
        void setPos(const v3f &pos);
        void moveTo(v3f pos, bool continuous);
index 609d8c3462dcf028592a83a6035f794787f36ec1..ba76d47464f1ccf1ff00cd950909085b54308dd0 100644 (file)
@@ -41,8 +41,10 @@ ServerModManager::ServerModManager(const std::string &worldpath) :
        SubgameSpec gamespec = findWorldSubgame(worldpath);
 
        // Add all game mods and all world mods
-       addModsInPath(gamespec.gamemods_path);
-       addModsInPath(worldpath + DIR_DELIM + "worldmods");
+       std::string game_virtual_path;
+       game_virtual_path.append("games/").append(gamespec.id).append("/mods");
+       addModsInPath(gamespec.gamemods_path, game_virtual_path);
+       addModsInPath(worldpath + DIR_DELIM + "worldmods", "worldmods");
 
        // Load normal mods
        std::string worldmt = worldpath + DIR_DELIM + "world.mt";
index d4d036726dc391fd110f04f82481df9574d29db1..d076d578342906a900f9f87874412531daca2d1f 100644 (file)
@@ -409,10 +409,11 @@ void PlayerSAO::setLookPitchAndSend(const float pitch)
        m_env->getGameDef()->SendMovePlayer(m_peer_id);
 }
 
-u16 PlayerSAO::punch(v3f dir,
+u32 PlayerSAO::punch(v3f dir,
        const ToolCapabilities *toolcap,
        ServerActiveObject *puncher,
-       float time_from_last_punch)
+       float time_from_last_punch,
+       u16 initial_wear)
 {
        if (!toolcap)
                return 0;
@@ -430,7 +431,7 @@ u16 PlayerSAO::punch(v3f dir,
 
        s32 old_hp = getHP();
        HitParams hitparams = getHitParams(m_armor_groups, toolcap,
-                       time_from_last_punch);
+                       time_from_last_punch, initial_wear);
 
        PlayerSAO *playersao = m_player->getPlayerSAO();
 
@@ -462,35 +463,33 @@ void PlayerSAO::rightClick(ServerActiveObject *clicker)
        m_env->getScriptIface()->on_rightclickplayer(this, clicker);
 }
 
-void PlayerSAO::setHP(s32 hp, const PlayerHPChangeReason &reason)
+void PlayerSAO::setHP(s32 target_hp, const PlayerHPChangeReason &reason, bool from_client)
 {
-       if (hp == (s32)m_hp)
-               return; // Nothing to do
-
-       if (m_hp <= 0 && hp < (s32)m_hp)
-               return; // Cannot take more damage
+       target_hp = rangelim(target_hp, 0, U16_MAX);
 
-       {
-               s32 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - m_hp, reason);
-               if (hp_change == 0)
-                       return;
+       if (target_hp == m_hp)
+               return; // Nothing to do
 
-               hp = m_hp + hp_change;
-       }
+       s32 hp_change = m_env->getScriptIface()->on_player_hpchange(this, target_hp - (s32)m_hp, reason);
 
-       s32 oldhp = m_hp;
-       hp = rangelim(hp, 0, m_prop.hp_max);
+       s32 hp = (s32)m_hp + std::min(hp_change, U16_MAX); // Protection against s32 overflow
+       hp = rangelim(hp, 0, U16_MAX);
 
-       if (hp < oldhp && isImmortal())
-               return; // Do not allow immortal players to be damaged
+       if (hp > m_prop.hp_max)
+               hp = m_prop.hp_max;
 
-       m_hp = hp;
+       if (hp < m_hp && isImmortal())
+               hp = m_hp; // Do not allow immortal players to be damaged
 
        // Update properties on death
-       if ((hp == 0) != (oldhp == 0))
+       if ((hp == 0) != (m_hp == 0))
                m_properties_sent = false;
 
-       m_env->getGameDef()->SendPlayerHPOrDie(this, reason);
+       if (hp != m_hp) {
+               m_hp = hp;
+               m_env->getGameDef()->HandlePlayerHPChange(this, reason);
+       } else if (from_client)
+               m_env->getGameDef()->SendPlayerHP(this);
 }
 
 void PlayerSAO::setBreath(const u16 breath, bool send)
index 8e2d8803fcfdc305140efc58374120558df3fa58..1067801e7bdfcafe36b7d0b374ee42f3dbb7e246 100644 (file)
@@ -72,24 +72,24 @@ class PlayerSAO : public UnitSAO
        PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t peer_id_,
                        bool is_singleplayer);
 
-       ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_PLAYER; }
-       ActiveObjectType getSendType() const { return ACTIVEOBJECT_TYPE_GENERIC; }
-       std::string getDescription();
+       ActiveObjectType getType() const override { return ACTIVEOBJECT_TYPE_PLAYER; }
+       ActiveObjectType getSendType() const override { return ACTIVEOBJECT_TYPE_GENERIC; }
+       std::string getDescription() override;
 
        /*
                Active object <-> environment interface
        */
 
-       void addedToEnvironment(u32 dtime_s);
-       void removingFromEnvironment();
-       bool isStaticAllowed() const { return false; }
-       bool shouldUnload() const { return false; }
-       std::string getClientInitializationData(u16 protocol_version);
-       void getStaticData(std::string *result) const;
-       void step(float dtime, bool send_recommended);
+       void addedToEnvironment(u32 dtime_s) override;
+       void removingFromEnvironment() override;
+       bool isStaticAllowed() const override { return false; }
+       bool shouldUnload() const override { return false; }
+       std::string getClientInitializationData(u16 protocol_version) override;
+       void getStaticData(std::string *result) const override;
+       void step(float dtime, bool send_recommended) override;
        void setBasePosition(const v3f &position);
-       void setPos(const v3f &pos);
-       void moveTo(v3f pos, bool continuous);
+       void setPos(const v3f &pos) override;
+       void moveTo(v3f pos, bool continuous) override;
        void setPlayerYaw(const float yaw);
        // Data should not be sent at player initialization
        void setPlayerYawAndSend(const float yaw);
@@ -109,10 +109,14 @@ class PlayerSAO : public UnitSAO
                Interaction interface
        */
 
-       u16 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher,
-                       float time_from_last_punch);
-       void rightClick(ServerActiveObject *clicker);
-       void setHP(s32 hp, const PlayerHPChangeReason &reason);
+       u32 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher,
+                       float time_from_last_punch, u16 initial_wear = 0) override;
+       void rightClick(ServerActiveObject *clicker) override;
+       void setHP(s32 hp, const PlayerHPChangeReason &reason) override
+       {
+               return setHP(hp, reason, false);
+       }
+       void setHP(s32 hp, const PlayerHPChangeReason &reason, bool from_client);
        void setHPRaw(u16 hp) { m_hp = hp; }
        u16 getBreath() const { return m_breath; }
        void setBreath(const u16 breath, bool send = true);
@@ -120,13 +124,13 @@ class PlayerSAO : public UnitSAO
        /*
                Inventory interface
        */
-       Inventory *getInventory() const;
-       InventoryLocation getInventoryLocation() const;
-       void setInventoryModified() {}
-       std::string getWieldList() const { return "main"; }
-       u16 getWieldIndex() const;
-       ItemStack getWieldedItem(ItemStack *selected, ItemStack *hand = nullptr) const;
-       bool setWieldedItem(const ItemStack &item);
+       Inventory *getInventory() const override;
+       InventoryLocation getInventoryLocation() const override;
+       void setInventoryModified() override {}
+       std::string getWieldList() const override { return "main"; }
+       u16 getWieldIndex() const override;
+       ItemStack getWieldedItem(ItemStack *selected, ItemStack *hand = nullptr) const override;
+       bool setWieldedItem(const ItemStack &item) override;
 
        /*
                PlayerSAO-specific
@@ -167,9 +171,9 @@ class PlayerSAO : public UnitSAO
                m_is_singleplayer = is_singleplayer;
        }
 
-       bool getCollisionBox(aabb3f *toset) const;
-       bool getSelectionBox(aabb3f *toset) const;
-       bool collideWithObjects() const { return true; }
+       bool getCollisionBox(aabb3f *toset) const override;
+       bool getSelectionBox(aabb3f *toset) const override;
+       bool collideWithObjects() const override { return true; }
 
        void finalize(RemotePlayer *player, const std::set<std::string> &privs);
 
index 51f44591427df4d373cb6025dc172e7142fe4320..5b0ee2d9b3127bd1575419930fc697d3dd8d2851 100644 (file)
@@ -145,11 +145,12 @@ class ServerActiveObject : public ActiveObject
        virtual bool shouldUnload() const
        { return true; }
 
-       // Returns tool wear
-       virtual u16 punch(v3f dir,
+       // Returns added tool wear
+       virtual u32 punch(v3f dir,
                        const ToolCapabilities *toolcap = nullptr,
                        ServerActiveObject *puncher = nullptr,
-                       float time_from_last_punch = 1000000.0f)
+                       float time_from_last_punch = 1000000.0f,
+                       u16 initial_wear = 0)
        { return 0; }
        virtual void rightClick(ServerActiveObject *clicker)
        {}
index 3aee003b4876423ae35972e1d0fa11940fe4e15a..63d1645cb5699f7ec188aeffcf0d2be237801364 100644 (file)
@@ -39,24 +39,29 @@ ServerInventoryManager::~ServerInventoryManager()
 
 Inventory *ServerInventoryManager::getInventory(const InventoryLocation &loc)
 {
+       // No m_env check here: allow creation and modification of detached inventories
+
        switch (loc.type) {
        case InventoryLocation::UNDEFINED:
        case InventoryLocation::CURRENT_PLAYER:
                break;
        case InventoryLocation::PLAYER: {
+               if (!m_env)
+                       return nullptr;
+
                RemotePlayer *player = m_env->getPlayer(loc.name.c_str());
                if (!player)
                        return NULL;
+
                PlayerSAO *playersao = player->getPlayerSAO();
-               if (!playersao)
-                       return NULL;
-               return playersao->getInventory();
+               return playersao ? playersao->getInventory() : nullptr;
        } break;
        case InventoryLocation::NODEMETA: {
+               if (!m_env)
+                       return nullptr;
+
                NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p);
-               if (!meta)
-                       return NULL;
-               return meta->getInventory();
+               return meta ? meta->getInventory() : nullptr;
        } break;
        case InventoryLocation::DETACHED: {
                auto it = m_detached_inventories.find(loc.name);
@@ -151,12 +156,13 @@ bool ServerInventoryManager::removeDetachedInventory(const std::string &name)
        const std::string &owner = inv_it->second.owner;
 
        if (!owner.empty()) {
-               RemotePlayer *player = m_env->getPlayer(owner.c_str());
-
-               if (player && player->getPeerId() != PEER_ID_INEXISTENT)
-                       m_env->getGameDef()->sendDetachedInventory(
-                                       nullptr, name, player->getPeerId());
+               if (m_env) {
+                       RemotePlayer *player = m_env->getPlayer(owner.c_str());
 
+                       if (player && player->getPeerId() != PEER_ID_INEXISTENT)
+                               m_env->getGameDef()->sendDetachedInventory(
+                                               nullptr, name, player->getPeerId());
+               }
        } else if (m_env) {
                // Notify all players about the change as soon ServerEnv exists
                m_env->getGameDef()->sendDetachedInventory(
index acbdd478aa4ad0486bae29b407bf1c4022ebf73f..9a49b0f4375a8ca1735ff2fa1535c4d162572e46 100644 (file)
@@ -84,8 +84,11 @@ void UnitSAO::setBonePosition(const std::string &bone, v3f position, v3f rotatio
 
 void UnitSAO::getBonePosition(const std::string &bone, v3f *position, v3f *rotation)
 {
-       *position = m_bone_position[bone].X;
-       *rotation = m_bone_position[bone].Y;
+       auto it = m_bone_position.find(bone);
+       if (it != m_bone_position.end()) {
+               *position = it->second.X;
+               *rotation = it->second.Y;
+       }
 }
 
 // clang-format off
index b8ba25235ef330dd1dca98aa49c4ca4b3ee5f992..6a9001052e2008c3817b324f1b7d93c20cd2e67e 100644 (file)
@@ -393,7 +393,7 @@ static std::random_device seed;
 
 ServerEnvironment::ServerEnvironment(ServerMap *map,
        ServerScripting *scriptIface, Server *server,
-       const std::string &path_world):
+       const std::string &path_world, MetricsBackend *mb):
        Environment(server),
        m_map(map),
        m_script(scriptIface),
@@ -460,6 +460,15 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
 
        m_player_database = openPlayerDatabase(player_backend_name, path_world, conf);
        m_auth_database = openAuthDatabase(auth_backend_name, path_world, conf);
+
+       m_step_time_counter = mb->addCounter(
+               "minetest_env_step_time", "Time spent in environment step (in microseconds)");
+
+       m_active_block_gauge = mb->addGauge(
+               "minetest_env_active_blocks", "Number of active blocks");
+
+       m_active_object_gauge = mb->addGauge(
+               "minetest_env_active_objects", "Number of active objects");
 }
 
 ServerEnvironment::~ServerEnvironment()
@@ -552,10 +561,8 @@ bool ServerEnvironment::removePlayerFromDatabase(const std::string &name)
 void ServerEnvironment::kickAllPlayers(AccessDeniedCode reason,
        const std::string &str_reason, bool reconnect)
 {
-       for (RemotePlayer *player : m_players) {
-               m_server->DenyAccessVerCompliant(player->getPeerId(),
-                       player->protocol_version, reason, str_reason, reconnect);
-       }
+       for (RemotePlayer *player : m_players)
+               m_server->DenyAccess(player->getPeerId(), reason, str_reason, reconnect);
 }
 
 void ServerEnvironment::saveLoadedPlayers(bool force)
@@ -892,7 +899,7 @@ class ABMHandler
                        for (ActiveABM &aabm : *m_aabms[c]) {
                                if ((p.Y < aabm.min_y) || (p.Y > aabm.max_y))
                                        continue;
-                               
+
                                if (myrand() % aabm.chance != 0)
                                        continue;
 
@@ -1285,6 +1292,8 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode)
 void ServerEnvironment::step(float dtime)
 {
        ScopeProfiler sp2(g_profiler, "ServerEnv::step()", SPT_AVG);
+       const auto start_time = porting::getTimeUs();
+
        /* Step time of day */
        stepTimeOfDay(dtime);
 
@@ -1354,6 +1363,8 @@ void ServerEnvironment::step(float dtime)
                m_active_blocks.update(players, active_block_range, active_object_range,
                        blocks_removed, blocks_added);
 
+               m_active_block_gauge->set(m_active_blocks.size());
+
                /*
                        Handle removed blocks
                */
@@ -1483,6 +1494,8 @@ void ServerEnvironment::step(float dtime)
        */
        m_script->environment_Step(dtime);
 
+       m_script->stepAsync();
+
        /*
                Step active objects
        */
@@ -1497,9 +1510,12 @@ void ServerEnvironment::step(float dtime)
                        send_recommended = true;
                }
 
-               auto cb_state = [this, dtime, send_recommended] (ServerActiveObject *obj) {
+               u32 object_count = 0;
+
+               auto cb_state = [&] (ServerActiveObject *obj) {
                        if (obj->isGone())
                                return;
+                       object_count++;
 
                        // Step object
                        obj->step(dtime, send_recommended);
@@ -1507,6 +1523,8 @@ void ServerEnvironment::step(float dtime)
                        obj->dumpAOMessagesToQueue(m_active_object_messages);
                };
                m_ao_manager.step(dtime, cb_state);
+
+               m_active_object_gauge->set(object_count);
        }
 
        /*
@@ -1548,6 +1566,9 @@ void ServerEnvironment::step(float dtime)
 
        // Send outdated detached inventories
        m_server->sendDetachedInventories(PEER_ID_INEXISTENT, true);
+
+       const auto end_time = porting::getTimeUs();
+       m_step_time_counter->increment(end_time - start_time);
 }
 
 ServerEnvironment::BlockStatus ServerEnvironment::getBlockStatus(v3s16 blockpos)
index 8733c2dd2e124ae475b4ba02cb3f98d80109e2ce..5dc329a60e8f531a686ac4020cea6607a0bc3f1a 100644 (file)
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "server/activeobjectmgr.h"
 #include "util/numeric.h"
+#include "util/metricsbackend.h"
 #include <set>
 #include <random>
 
@@ -167,19 +168,21 @@ class ActiveBlockList
                std::set<v3s16> &blocks_removed,
                std::set<v3s16> &blocks_added);
 
-       bool contains(v3s16 p){
+       bool contains(v3s16 p) const {
                return (m_list.find(p) != m_list.end());
        }
 
-       void clear(){
+       auto size() const {
+               return m_list.size();
+       }
+
+       void clear() {
                m_list.clear();
        }
 
        std::set<v3s16> m_list;
        std::set<v3s16> m_abm_list;
        std::set<v3s16> m_forceloaded_list;
-
-private:
 };
 
 /*
@@ -198,7 +201,7 @@ class ServerEnvironment : public Environment
 {
 public:
        ServerEnvironment(ServerMap *map, ServerScripting *scriptIface,
-               Server *server, const std::string &path_world);
+               Server *server, const std::string &path_world, MetricsBackend *mb);
        ~ServerEnvironment();
 
        Map & getMap();
@@ -487,5 +490,10 @@ class ServerEnvironment : public Environment
        std::unordered_map<u32, float> m_particle_spawners;
        std::unordered_map<u32, u16> m_particle_spawner_attachments;
 
+       // Environment metrics
+       MetricCounterPtr m_step_time_counter;
+       MetricGaugePtr m_active_block_gauge;
+       MetricGaugePtr m_active_object_gauge;
+
        ServerActiveObject* createSAO(ActiveObjectType type, v3f pos, const std::string &data);
 };
index 3bcab3d58ae4c35575becb6c5e95ca72b32bc025..29e3ac9a6ad4f84e9a077948167c4348701c6b32 100644 (file)
@@ -97,6 +97,7 @@ void sendAnnounce(AnnounceAction action,
        }
 
        HTTPFetchRequest fetch_request;
+       fetch_request.caller = HTTPFETCH_PRINT_ERR;
        fetch_request.url = g_settings->get("serverlist_url") + std::string("/announce");
        fetch_request.method = HTTP_POST;
        fetch_request.fields["json"] = fastWriteJson(server);
index f4de5bec90d755edc86e684517f678bb8512a902..0e44ee0bcb6c9adbc7915d228843a8c5fd85298d 100644 (file)
@@ -88,7 +88,7 @@ void SettingsHierarchy::onLayerCreated(int layer, Settings *obj)
 
 void SettingsHierarchy::onLayerRemoved(int layer)
 {
-       assert(layer >= 0 && layer < layers.size());
+       assert(layer >= 0 && layer < (int)layers.size());
        layers[layer] = nullptr;
        if (this == &g_hierarchy && layer == (int)SL_GLOBAL)
                g_settings = nullptr;
@@ -104,8 +104,7 @@ Settings *Settings::createLayer(SettingsLayer sl, const std::string &end_tag)
 
 Settings *Settings::getLayer(SettingsLayer sl)
 {
-       sanity_check((int)sl >= 0 && sl < SL_TOTAL_COUNT);
-       return g_hierarchy.layers[(int)sl];
+       return g_hierarchy.getLayer(sl);
 }
 
 
@@ -660,9 +659,7 @@ bool Settings::getNoiseParamsFromGroup(const std::string &name,
 
 bool Settings::exists(const std::string &name) const
 {
-       MutexAutoLock lock(m_mutex);
-
-       if (m_settings.find(name) != m_settings.end())
+       if (existsLocal(name))
                return true;
        if (auto parent = getParent())
                return parent->exists(name);
@@ -670,6 +667,14 @@ bool Settings::exists(const std::string &name) const
 }
 
 
+bool Settings::existsLocal(const std::string &name) const
+{
+       MutexAutoLock lock(m_mutex);
+
+       return m_settings.find(name) != m_settings.end();
+}
+
+
 std::vector<std::string> Settings::getNames() const
 {
        MutexAutoLock lock(m_mutex);
index 4e32a34881094582246e68820aff5ad8c8955b03..767d057f9c1b77eb4b11e7fe4095121a32eb0aa3 100644 (file)
@@ -172,9 +172,12 @@ class Settings {
        bool getNoiseParamsFromValue(const std::string &name, NoiseParams &np) const;
        bool getNoiseParamsFromGroup(const std::string &name, NoiseParams &np) const;
 
-       // return all keys used
+       // return all keys used in this object
        std::vector<std::string> getNames() const;
+       // check if setting exists anywhere in the hierarchy
        bool exists(const std::string &name) const;
+       // check if setting exists in this object ("locally")
+       bool existsLocal(const std::string &name) const;
 
 
        /***************************************
index 49591d1ee86bc7694de846de4e32cb5382519abd..d7811bafa9365cef0a3dfa5cbe9b4fd9c55c11d7 100644 (file)
@@ -1,5 +1,5 @@
 // This file is automatically generated
-// It conatins a bunch of fake gettext calls, to tell xgettext about the strings in config files
+// It contains a bunch of fake gettext calls, to tell xgettext about the strings in config files
 // To update it, refer to the bottom of builtin/mainmenu/dlg_settings_advanced.lua
 
 fake_function() {
@@ -54,10 +54,10 @@ fake_function() {
        gettext("The type of joystick");
        gettext("Joystick button repetition interval");
        gettext("The time in seconds it takes between repeated events\nwhen holding down a joystick button combination.");
-       gettext("Joystick deadzone");
-       gettext("The deadzone of the joystick");
+       gettext("Joystick dead zone");
+       gettext("The dead zone of the joystick");
        gettext("Joystick frustum sensitivity");
-       gettext("The sensitivity of the joystick axes for moving the\ningame view frustum around.");
+       gettext("The sensitivity of the joystick axes for moving the\nin-game view frustum around.");
        gettext("Forward key");
        gettext("Key for moving the player forward.\nSee http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3");
        gettext("Backward key");
@@ -203,8 +203,8 @@ fake_function() {
        gettext("Graphics");
        gettext("In-Game");
        gettext("Basic");
-       gettext("Show nametag backgrounds by default");
-       gettext("Whether nametag backgrounds should be shown by default.\nMods may still set a background.");
+       gettext("Show name tag backgrounds by default");
+       gettext("Whether name tag backgrounds should be shown by default.\nMods may still set a background.");
        gettext("VBO");
        gettext("Enable vertex buffer objects.\nThis should greatly improve graphics performance.");
        gettext("Fog");
@@ -215,6 +215,8 @@ fake_function() {
        gettext("Connects glass if supported by node.");
        gettext("Smooth lighting");
        gettext("Enable smooth lighting with simple ambient occlusion.\nDisable for speed or for different looks.");
+       gettext("Tradeoffs for performance");
+       gettext("Enables tradeoffs that reduce CPU load or increase rendering performance\nat the expense of minor visual glitches that do not impact game playability.");
        gettext("Clouds");
        gettext("Clouds are a client side effect.");
        gettext("3D clouds");
@@ -225,7 +227,7 @@ fake_function() {
        gettext("Adds particles when digging a node.");
        gettext("Filtering");
        gettext("Mipmapping");
-       gettext("Use mip mapping to scale textures. May slightly increase performance,\nespecially when using a high resolution texture pack.\nGamma correct downscaling is not supported.");
+       gettext("Use mipmapping to scale textures. May slightly increase performance,\nespecially when using a high resolution texture pack.\nGamma correct downscaling is not supported.");
        gettext("Anisotropic filtering");
        gettext("Use anisotropic filtering when viewing at textures from an angle.");
        gettext("Bilinear filtering");
@@ -235,7 +237,7 @@ fake_function() {
        gettext("Clean transparent textures");
        gettext("Filtered textures can blend RGB values with fully-transparent neighbors,\nwhich PNG optimizers usually discard, often resulting in dark or\nlight edges to transparent textures. Apply a filter to clean that up\nat texture load time. This is automatically enabled if mipmapping is enabled.");
        gettext("Minimum texture size");
-       gettext("When using bilinear/trilinear/anisotropic filters, low-resolution textures\ncan be blurred, so automatically upscale them with nearest-neighbor\ninterpolation to preserve crisp pixels. This sets the minimum texture size\nfor the upscaled textures; higher values look sharper, but require more\nmemory.  Powers of 2 are recommended. This setting is ONLY applies if\nbilinear/trilinear/anisotropic filtering is enabled.\nThis is also used as the base node texture size for world-aligned\ntexture autoscaling.");
+       gettext("When using bilinear/trilinear/anisotropic filters, low-resolution textures\ncan be blurred, so automatically upscale them with nearest-neighbor\ninterpolation to preserve crisp pixels. This sets the minimum texture size\nfor the upscaled textures; higher values look sharper, but require more\nmemory. Powers of 2 are recommended. This setting is ONLY applied if\nbilinear/trilinear/anisotropic filtering is enabled.\nThis is also used as the base node texture size for world-aligned\ntexture autoscaling.");
        gettext("FSAA");
        gettext("Use multi-sample antialiasing (MSAA) to smooth out block edges.\nThis algorithm smooths out the 3D viewport while keeping the image sharp,\nbut it doesn't affect the insides of textures\n(which is especially noticeable with transparent textures).\nVisible spaces appear between nodes when shaders are disabled.\nIf set to 0, MSAA is disabled.\nA restart is required after changing this option.");
        gettext("Undersampling");
@@ -264,26 +266,26 @@ fake_function() {
        gettext("Dynamic shadows");
        gettext("Dynamic shadows");
        gettext("Set to true to enable Shadow Mapping.\nRequires shaders to be enabled.");
-       gettext("Shadow strength");
-       gettext("Set the shadow strength.\nLower value means lighter shadows, higher value means darker shadows.");
+       gettext("Shadow strength gamma");
+       gettext("Set the shadow strength gamma.\nAdjusts the intensity of in-game dynamic shadows.\nLower value means lighter shadows, higher value means darker shadows.");
        gettext("Shadow map max distance in nodes to render shadows");
        gettext("Maximum distance to render shadows.");
        gettext("Shadow map texture size");
-       gettext("Texture size to render the shadow map on.\nThis must be a power of two.\nBigger numbers create better shadowsbut it is also more expensive.");
+       gettext("Texture size to render the shadow map on.\nThis must be a power of two.\nBigger numbers create better shadows but it is also more expensive.");
        gettext("Shadow map texture in 32 bits");
        gettext("Sets shadow texture quality to 32 bits.\nOn false, 16 bits texture will be used.\nThis can cause much more artifacts in the shadow.");
        gettext("Poisson filtering");
-       gettext("Enable poisson disk filtering.\nOn true uses poisson disk to make \"soft shadows\". Otherwise uses PCF filtering.");
+       gettext("Enable Poisson disk filtering.\nOn true uses Poisson disk to make \"soft shadows\". Otherwise uses PCF filtering.");
        gettext("Shadow filter quality");
-       gettext("Define shadow filtering quality\nThis simulates the soft shadows effect by applying a PCF or poisson disk\nbut also uses more resources.");
+       gettext("Define shadow filtering quality.\nThis simulates the soft shadows effect by applying a PCF or Poisson disk\nbut also uses more resources.");
        gettext("Colored shadows");
-       gettext("Enable colored shadows. \nOn true translucent nodes cast colored shadows. This is expensive.");
-       gettext("Map update time");
-       gettext("Set the shadow update time.\nLower value means shadows and map updates faster, but it consume more resources.\nMinimun value 0.001 seconds max value 0.2 seconds");
+       gettext("Enable colored shadows.\nOn true translucent nodes cast colored shadows. This is expensive.");
+       gettext("Map shadows update frames");
+       gettext("Spread a complete update of shadow map over given amount of frames.\nHigher values might make shadows laggy, lower values\nwill consume more resources.\nMinimum value: 1; maximum value: 16");
        gettext("Soft shadow radius");
-       gettext("Set the soft shadow radius size.\nLower values mean sharper shadows bigger values softer.\nMinimun value 1.0 and max value 10.0");
+       gettext("Set the soft shadow radius size.\nLower values mean sharper shadows, bigger values mean softer shadows.\nMinimum value: 1.0; maximum value: 10.0");
        gettext("Sky Body Orbit Tilt");
-       gettext("Set the tilt of Sun/Moon orbit in degrees\nValue of 0 means no tilt / vertical orbit.\nMinimun value 0.0 and max value 60.0");
+       gettext("Set the tilt of Sun/Moon orbit in degrees.\nValue of 0 means no tilt / vertical orbit.\nMinimum value: 0.0; maximum value: 60.0");
        gettext("Advanced");
        gettext("Arm inertia");
        gettext("Arm inertia, gives a more realistic movement of\nthe arm when the camera moves.");
@@ -356,7 +358,7 @@ fake_function() {
        gettext("Crosshair color");
        gettext("Crosshair color (R,G,B).\nAlso controls the object crosshair color");
        gettext("Crosshair alpha");
-       gettext("Crosshair alpha (opaqueness, between 0 and 255).\nAlso controls the object crosshair color");
+       gettext("Crosshair alpha (opaqueness, between 0 and 255).\nThis also applies to the object crosshair.");
        gettext("Recent Chat Messages");
        gettext("Maximum number of recent chat messages to show");
        gettext("Desynchronize block animation");
@@ -364,7 +366,7 @@ fake_function() {
        gettext("Maximum hotbar width");
        gettext("Maximum proportion of current window to be used for hotbar.\nUseful if there's something to be displayed right or left of hotbar.");
        gettext("HUD scale factor");
-       gettext("Modifies the size of the hudbar elements.");
+       gettext("Modifies the size of the HUD elements.");
        gettext("Mesh cache");
        gettext("Enables caching of facedir rotated meshes.");
        gettext("Mapblock mesh generation delay");
@@ -393,6 +395,8 @@ fake_function() {
        gettext("World-aligned textures may be scaled to span several nodes. However,\nthe server may not send the scale you want, especially if you use\na specially-designed texture pack; with this option, the client tries\nto determine the scale automatically basing on the texture size.\nSee also texture_min_size.\nWarning: This option is EXPERIMENTAL!");
        gettext("Show entity selection boxes");
        gettext("Show entity selection boxes\nA restart is required after changing this.");
+       gettext("Transparency Sorting Distance");
+       gettext("Distance in nodes at which transparency depth sorting is enabled\nUse this to limit the performance impact of transparency depth sorting");
        gettext("Menus");
        gettext("Clouds in menu");
        gettext("Use a cloud animation for the main menu background.");
@@ -406,8 +410,6 @@ fake_function() {
        gettext("Delay showing tooltips, stated in milliseconds.");
        gettext("Append item name");
        gettext("Append item name to tooltip.");
-       gettext("FreeType fonts");
-       gettext("Whether FreeType fonts are used, requires FreeType support to be compiled in.\nIf disabled, bitmap and XML vectors fonts are used instead.");
        gettext("Font bold by default");
        gettext("Font italic by default");
        gettext("Font shadow");
@@ -415,21 +417,25 @@ fake_function() {
        gettext("Font shadow alpha");
        gettext("Opaqueness (alpha) of the shadow behind the default font, between 0 and 255.");
        gettext("Font size");
-       gettext("Font size of the default font in point (pt).");
+       gettext("Font size of the default font where 1 unit = 1 pixel at 96 DPI");
+       gettext("Font size divisible by");
+       gettext("For pixel-style fonts that do not scale well, this ensures that font sizes used\nwith this font will always be divisible by this value, in pixels. For instance,\na pixel font 16 pixels tall should have this set to 16, so it will only ever be\nsized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32.");
        gettext("Regular font path");
-       gettext("Path to the default font.\nIf “freetype” setting is enabled: Must be a TrueType font.\nIf “freetype” setting is disabled: Must be a bitmap or XML vectors font.\nThe fallback font will be used if the font cannot be loaded.");
+       gettext("Path to the default font. Must be a TrueType font.\nThe fallback font will be used if the font cannot be loaded.");
        gettext("Bold font path");
        gettext("Italic font path");
        gettext("Bold and italic font path");
        gettext("Monospace font size");
-       gettext("Font size of the monospace font in point (pt).");
+       gettext("Font size of the monospace font where 1 unit = 1 pixel at 96 DPI");
+       gettext("Monospace font size divisible by");
+       gettext("For pixel-style fonts that do not scale well, this ensures that font sizes used\nwith this font will always be divisible by this value, in pixels. For instance,\na pixel font 16 pixels tall should have this set to 16, so it will only ever be\nsized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32.");
        gettext("Monospace font path");
-       gettext("Path to the monospace font.\nIf “freetype” setting is enabled: Must be a TrueType font.\nIf “freetype” setting is disabled: Must be a bitmap or XML vectors font.\nThis font is used for e.g. the console and profiler screen.");
+       gettext("Path to the monospace font. Must be a TrueType font.\nThis font is used for e.g. the console and profiler screen.");
        gettext("Bold monospace font path");
        gettext("Italic monospace font path");
        gettext("Bold and italic monospace font path");
        gettext("Fallback font path");
-       gettext("Path of the fallback font.\nIf “freetype” setting is enabled: Must be a TrueType font.\nIf “freetype” setting is disabled: Must be a bitmap or XML vectors font.\nThis font will be used for certain languages or if the default font is unavailable.");
+       gettext("Path of the fallback font. Must be a TrueType font.\nThis font will be used for certain languages or if the default font is unavailable.");
        gettext("Chat font size");
        gettext("Font size of the recent chat text and chat prompt in point (pt).\nValue 0 will use the default font size.");
        gettext("Screenshot folder");
@@ -441,6 +447,8 @@ fake_function() {
        gettext("Advanced");
        gettext("DPI");
        gettext("Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens.");
+       gettext("Display Density Scaling Factor");
+       gettext("Adjust the detected display density, used for scaling UI elements.");
        gettext("Enable console window");
        gettext("Windows systems only: Start Minetest with the command line window in the background.\nContains the same information as the file debug.txt (default name).");
        gettext("Sound");
@@ -451,13 +459,17 @@ fake_function() {
        gettext("Mute sound");
        gettext("Whether to mute sounds. You can unmute sounds at any time, unless the\nsound system is disabled (enable_sound=false).\nIn-game, you can toggle the mute state with the mute key or by using the\npause menu.");
        gettext("Client");
+       gettext("Chat weblinks");
+       gettext("Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output.");
+       gettext("Weblink color");
+       gettext("Optional override for chat weblink color.");
        gettext("Network");
        gettext("Server address");
        gettext("Address to connect to.\nLeave this blank to start a local server.\nNote that the address field in the main menu overrides this setting.");
        gettext("Remote port");
        gettext("Port to connect to (UDP).\nNote that the port field in the main menu overrides this setting.");
        gettext("Prometheus listener address");
-       gettext("Prometheus listener address.\nIf minetest is compiled with ENABLE_PROMETHEUS option enabled,\nenable metrics listener for Prometheus on that address.\nMetrics can be fetch on http://127.0.0.1:30000/metrics");
+       gettext("Prometheus listener address.\nIf Minetest is compiled with ENABLE_PROMETHEUS option enabled,\nenable metrics listener for Prometheus on that address.\nMetrics can be fetched on http://127.0.0.1:30000/metrics");
        gettext("Saving map received from server");
        gettext("Save the map received by the client on disk.");
        gettext("Connect to external media server");
@@ -513,7 +525,7 @@ fake_function() {
        gettext("Max. packets per iteration");
        gettext("Maximum number of packets sent per send step, if you have a slow connection\ntry reducing it, but don't reduce it to a number below double of targeted\nclient number.");
        gettext("Map Compression Level for Network Transfer");
-       gettext("ZLib compression level to use when sending mapblocks to the client.\n-1 - Zlib's default compression level\n0 - no compresson, fastest\n9 - best compression, slowest\n(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)");
+       gettext("Compression level to use when sending mapblocks to the client.\n-1 - use default compression level\n0 - least compression, fastest\n9 - best compression, slowest");
        gettext("Game");
        gettext("Default game");
        gettext("Default game when creating a new world.\nThis will be overridden when creating a world from the main menu.");
@@ -616,7 +628,7 @@ fake_function() {
        gettext("Deprecated Lua API handling");
        gettext("Handling for deprecated Lua API calls:\n-    none: Do not log deprecated calls\n-    log: mimic and log backtrace of deprecated call (default).\n-    error: abort on usage of deprecated call (suggested for mod developers).");
        gettext("Max. clearobjects extra blocks");
-       gettext("Number of extra blocks that can be loaded by /clearobjects at once.\nThis is a trade-off between sqlite transaction overhead and\nmemory consumption (4096=100MB, as a rule of thumb).");
+       gettext("Number of extra blocks that can be loaded by /clearobjects at once.\nThis is a trade-off between SQLite transaction overhead and\nmemory consumption (4096=100MB, as a rule of thumb).");
        gettext("Unload unused server data");
        gettext("How much the server will wait before unloading unused mapblocks.\nHigher value is smoother, but will use more RAM.");
        gettext("Maximum objects per block");
@@ -624,7 +636,7 @@ fake_function() {
        gettext("Synchronous SQLite");
        gettext("See https://www.sqlite.org/pragma.html#pragma_synchronous");
        gettext("Map Compression Level for Disk Storage");
-       gettext("ZLib compression level to use when saving mapblocks to disk.\n-1 - Zlib's default compression level\n0 - no compresson, fastest\n9 - best compression, slowest\n(levels 1-3 use Zlib's \"fast\" method, 4-9 use the normal method)");
+       gettext("Compression level to use when saving mapblocks to disk.\n-1 - use default compression level\n0 - least compression, fastest\n9 - best compression, slowest");
        gettext("Dedicated server step");
        gettext("Length of a server tick and the interval at which objects are generally updated over\nnetwork.");
        gettext("Active block management interval");
@@ -673,8 +685,8 @@ fake_function() {
        gettext("Instrument the action function of Active Block Modifiers on registration.");
        gettext("Loading Block Modifiers");
        gettext("Instrument the action function of Loading Block Modifiers on registration.");
-       gettext("Chatcommands");
-       gettext("Instrument chatcommands on registration.");
+       gettext("Chat commands");
+       gettext("Instrument chat commands on registration.");
        gettext("Global callbacks");
        gettext("Instrument global callback functions on registration.\n(anything you pass to a minetest.register_*() function)");
        gettext("Advanced");
@@ -716,7 +728,7 @@ fake_function() {
        gettext("Map generation limit");
        gettext("Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).\nOnly mapchunks completely within the mapgen limit are generated.\nValue is stored per-world.");
        gettext("Mapgen flags");
-       gettext("Global map generation attributes.\nIn Mapgen v6 the 'decorations' flag controls all decorations except trees\nand junglegrass, in all other mapgens this flag controls all decorations.");
+       gettext("Global map generation attributes.\nIn Mapgen v6 the 'decorations' flag controls all decorations except trees\nand jungle grass, in all other mapgens this flag controls all decorations.");
        gettext("Biome API temperature and humidity noise parameters");
        gettext("Heat noise");
        gettext("Temperature variation for biomes.");
index 1de494d69d2b4106d6f2356d197da930659126b6..f7f69442787319fefd9e647e65bd4ce508ccf39c 100644 (file)
@@ -68,11 +68,36 @@ struct StarParams
        f32 scale;
 };
 
+struct CloudParams
+{
+       float density;
+       video::SColor color_bright;
+       video::SColor color_ambient;
+       float thickness;
+       float height;
+       v2f speed;
+};
+
 // Utility class for setting default sky, sun, moon, stars values:
 class SkyboxDefaults
 {
 public:
-       const SkyColor getSkyColorDefaults()
+       SkyboxDefaults() = delete;
+
+       static const SkyboxParams getSkyDefaults()
+       {
+               SkyboxParams sky;
+               sky.bgcolor = video::SColor(255, 255, 255, 255);
+               sky.type = "regular";
+               sky.clouds = true;
+               sky.sky_color = getSkyColorDefaults();
+               sky.fog_sun_tint = video::SColor(255, 244, 125, 29);
+               sky.fog_moon_tint = video::SColorf(0.5, 0.6, 0.8, 1).toSColor();
+               sky.fog_tint_type = "default";
+               return sky;
+       }
+
+       static const SkyColor getSkyColorDefaults()
        {
                SkyColor sky;
                // Horizon colors
@@ -87,7 +112,7 @@ class SkyboxDefaults
                return sky;
        }
 
-       const SunParams getSunDefaults()
+       static const SunParams getSunDefaults()
        {
                SunParams sun;
                sun.visible = true;
@@ -99,7 +124,7 @@ class SkyboxDefaults
                return sun;
        }
 
-       const MoonParams getMoonDefaults()
+       static const MoonParams getMoonDefaults()
        {
                MoonParams moon;
                moon.visible = true;
@@ -109,7 +134,7 @@ class SkyboxDefaults
                return moon;
        }
 
-       const StarParams getStarDefaults()
+       static const StarParams getStarDefaults()
        {
                StarParams stars;
                stars.visible = true;
@@ -118,4 +143,16 @@ class SkyboxDefaults
                stars.scale = 1;
                return stars;
        }
+
+       static const CloudParams getCloudDefaults()
+       {
+               CloudParams clouds;
+               clouds.density = 0.4f;
+               clouds.color_bright = video::SColor(229, 240, 240, 255);
+               clouds.color_ambient = video::SColor(255, 0, 0, 0);
+               clouds.thickness = 16.0f;
+               clouds.height = 120;
+               clouds.speed = v2f(0.0f, -2.0f);
+               return clouds;
+       }
 };
index 9e3d33736190bc6ca2275d43b2ca84f37423c66a..b12261c3b8bac71e3c0fb37690ed8756d3495ea1 100644 (file)
@@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include <inttypes.h>
 #include "config.h"
 #if USE_CURSES
 #include "version.h"
@@ -398,7 +399,7 @@ void TerminalChatConsole::step(int ch)
        minutes = (float)minutes / 1000 * 60;
 
        if (m_game_time)
-               printw(" | Game %d Time of day %02d:%02d ",
+               printw(" | Game %" PRIu64 " Time of day %02d:%02d ",
                        m_game_time, hours, minutes);
 
        // draw text
index 5cfc609957eb5ed999afddb932c634a4f3f39be4..ef025ac1d0ea72e29808f5df61b4672149c35aab 100644 (file)
@@ -121,12 +121,12 @@ bool Thread::start()
                return false;
        }
 
-       // Allow spawned thread to continue
-       m_start_finished_mutex.unlock();
-
        while (!m_running)
                sleep_ms(1);
 
+       // Allow spawned thread to continue
+       m_start_finished_mutex.unlock();
+
        m_joinable = true;
 
        return true;
index 3f639a69ee3b7c1c40ce85a2eeaa22950e3c05e0..075c6b3c5ff13f8bb5e5ada473d85d7c8e80f7ca 100644 (file)
@@ -183,9 +183,74 @@ void ToolCapabilities::deserializeJson(std::istream &is)
        }
 }
 
+static u32 calculateResultWear(const u32 uses, const u16 initial_wear)
+{
+       if (uses == 0) {
+               // Trivial case: Infinite uses
+               return 0;
+       }
+       /* Finite uses. This is not trivial,
+       as the maximum wear is not neatly evenly divisible by
+       most possible uses numbers. For example, for 128
+       uses, the calculation of wear is trivial, as
+       65536 / 128 uses = 512 wear,
+       so the tool will get 512 wear 128 times in its lifetime.
+       But for a number like 130, this does not work:
+       65536 / 130 uses = 504.123... wear.
+       Since wear must be an integer, we will get
+       504*130 = 65520, which would lead to the wrong number
+       of uses.
+
+       Instead, we partition the "wear range" into blocks:
+       A block represents a single use and can be
+       of two possible sizes: normal and oversized.
+       A normal block is equal to floor(65536 / uses).
+       An oversized block is a normal block plus 1.
+       Then we determine how many oversized and normal
+       blocks we need and finally, whether we add
+       the normal wear or the oversized wear.
+
+       Example for 130 uses:
+       * Normal wear = 504
+       * Number of normal blocks = 114
+       * Oversized wear = 505
+       * Number of oversized blocks = 16
+
+       If we add everything together, we get:
+         114*504 + 16*505 = 65536
+       */
+       u32 result_wear;
+       u32 wear_normal = ((U16_MAX+1) / uses);
+       // Will be non-zero if its not evenly divisible
+       u16 blocks_oversize = (U16_MAX+1) % uses;
+       // Whether to add one extra wear point in case
+       // of oversized wear.
+       u16 wear_extra = 0;
+       if (blocks_oversize > 0) {
+               u16 blocks_normal = uses - blocks_oversize;
+               /* When the wear has reached this value, we
+                  know that wear_normal has been applied
+                  for blocks_normal times, therefore,
+                  only oversized blocks remain.
+                  This also implies the raw tool wear number
+                  increases a bit faster after this point,
+                  but this should be barely noticable by the
+                  player.
+               */
+               u16 wear_extra_at = blocks_normal * wear_normal;
+               if (initial_wear >= wear_extra_at) {
+                       wear_extra = 1;
+               }
+       }
+       result_wear = wear_normal + wear_extra;
+       return result_wear;
+}
+
 DigParams getDigParams(const ItemGroupList &groups,
-               const ToolCapabilities *tp)
+               const ToolCapabilities *tp,
+               const u16 initial_wear)
 {
+
        // Group dig_immediate defaults to fixed time and no wear
        if (tp->groupcaps.find("dig_immediate") == tp->groupcaps.cend()) {
                switch (itemgroup_get(groups, "dig_immediate")) {
@@ -201,7 +266,7 @@ DigParams getDigParams(const ItemGroupList &groups,
        // Values to be returned (with a bit of conversion)
        bool result_diggable = false;
        float result_time = 0.0;
-       float result_wear = 0.0;
+       u32 result_wear = 0;
        std::string result_main_group;
 
        int level = itemgroup_get(groups, "level");
@@ -224,22 +289,24 @@ DigParams getDigParams(const ItemGroupList &groups,
                if (!result_diggable || time < result_time) {
                        result_time = time;
                        result_diggable = true;
-                       if (cap.uses != 0)
-                               result_wear = 1.0 / cap.uses / pow(3.0, leveldiff);
-                       else
-                               result_wear = 0;
+                       // The actual number of uses increases
+                       // exponentially with leveldiff.
+                       // If the levels are equal, real_uses equals cap.uses.
+                       u32 real_uses = cap.uses * pow(3.0, leveldiff);
+                       real_uses = MYMIN(real_uses, U16_MAX);
+                       result_wear = calculateResultWear(real_uses, initial_wear);
                        result_main_group = groupname;
                }
        }
 
-       u16 wear_i = U16_MAX * result_wear;
-       return DigParams(result_diggable, result_time, wear_i, result_main_group);
+       return DigParams(result_diggable, result_time, result_wear, result_main_group);
 }
 
 HitParams getHitParams(const ItemGroupList &armor_groups,
-               const ToolCapabilities *tp, float time_from_last_punch)
+               const ToolCapabilities *tp, float time_from_last_punch,
+               u16 initial_wear)
 {
-       s16 damage = 0;
+       s32 damage = 0;
        float result_wear = 0.0f;
        float punch_interval_multiplier =
                        rangelim(time_from_last_punch / tp->full_punch_interval, 0.0f, 1.0f);
@@ -249,10 +316,14 @@ HitParams getHitParams(const ItemGroupList &armor_groups,
                damage += damageGroup.second * punch_interval_multiplier * armor / 100.0;
        }
 
-       if (tp->punch_attack_uses > 0)
-               result_wear = 1.0f / tp->punch_attack_uses * punch_interval_multiplier;
+       if (tp->punch_attack_uses > 0) {
+               result_wear = calculateResultWear(tp->punch_attack_uses, initial_wear);
+               result_wear *= punch_interval_multiplier;
+       }
+       // Keep damage in sane bounds for simplicity
+       damage = rangelim(damage, -U16_MAX, U16_MAX);
 
-       u16 wear_i = U16_MAX * result_wear;
+       u32 wear_i = (u32) result_wear;
        return {damage, wear_i};
 }
 
@@ -266,7 +337,8 @@ PunchDamageResult getPunchDamage(
                const ItemGroupList &armor_groups,
                const ToolCapabilities *toolcap,
                const ItemStack *punchitem,
-               float time_from_last_punch
+               float time_from_last_punch,
+               u16 initial_wear
 ){
        bool do_hit = true;
        {
@@ -286,7 +358,8 @@ PunchDamageResult getPunchDamage(
        if(do_hit)
        {
                HitParams hitparams = getHitParams(armor_groups, toolcap,
-                               time_from_last_punch);
+                               time_from_last_punch,
+                               punchitem->wear);
                result.did_punch = true;
                result.wear = hitparams.wear;
                result.damage = hitparams.hp;
index 59dd501f51de3a75b0694ff42cf47cf6c18df6cd..8409f59afcd234da41fb2b2b58bdd0b7738abde3 100644 (file)
@@ -88,10 +88,10 @@ struct DigParams
        // Digging time in seconds
        float time;
        // Caused wear
-       u16 wear;
+       u32 wear; // u32 because wear could be 65536 (single-use tool)
        std::string main_group;
 
-       DigParams(bool a_diggable = false, float a_time = 0.0f, u16 a_wear = 0,
+       DigParams(bool a_diggable = false, float a_time = 0.0f, u32 a_wear = 0,
                        const std::string &a_main_group = ""):
                diggable(a_diggable),
                time(a_time),
@@ -101,21 +101,24 @@ struct DigParams
 };
 
 DigParams getDigParams(const ItemGroupList &groups,
-               const ToolCapabilities *tp);
+               const ToolCapabilities *tp,
+               const u16 initial_wear = 0);
 
 struct HitParams
 {
-       s16 hp;
-       u16 wear;
+       s32 hp;
+       // Caused wear
+       u32 wear; // u32 because wear could be 65536 (single-use weapon)
 
-       HitParams(s16 hp_ = 0, u16 wear_ = 0):
+       HitParams(s32 hp_ = 0, u32 wear_ = 0):
                hp(hp_),
                wear(wear_)
        {}
 };
 
 HitParams getHitParams(const ItemGroupList &armor_groups,
-               const ToolCapabilities *tp, float time_from_last_punch);
+               const ToolCapabilities *tp, float time_from_last_punch,
+               u16 initial_wear = 0);
 
 HitParams getHitParams(const ItemGroupList &armor_groups,
                const ToolCapabilities *tp);
@@ -135,7 +138,8 @@ PunchDamageResult getPunchDamage(
                const ItemGroupList &armor_groups,
                const ToolCapabilities *toolcap,
                const ItemStack *punchitem,
-               float time_from_last_punch
+               float time_from_last_punch,
+               u16 initial_wear = 0
 );
 
 f32 getToolRange(const ItemDefinition &def_selected, const ItemDefinition &def_hand);
index 5703b890629684a40856d361911ab54858ee006a..84f769e879c6fcfff48ac72758867c4cf5f933b7 100644 (file)
@@ -11,14 +11,16 @@ set (UNITTEST_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/test_filepath.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_inventory.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_irrptr.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/test_lua.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/test_map.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_map_settings_manager.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_mapnode.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_modchannels.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/test_modmetadatadatabase.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_nodedef.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_noderesolver.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_noise.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_objdef.cpp
-       ${CMAKE_CURRENT_SOURCE_DIR}/test_player.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_profiler.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_random.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_schematic.cpp
@@ -33,6 +35,7 @@ set (UNITTEST_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/test_voxelarea.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_voxelalgorithms.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/test_voxelmanipulator.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/test_gettext.cpp
        PARENT_SCOPE)
 
 set (UNITTEST_CLIENT_SRCS
@@ -44,6 +47,7 @@ set (UNITTEST_CLIENT_SRCS
 
 set (TEST_WORLDDIR ${CMAKE_CURRENT_SOURCE_DIR}/test_world)
 set (TEST_SUBGAME_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../games/devtest)
+set (TEST_MOD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/test_mod)
 
 configure_file(
        "${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in"
index d4841d5593598f8c6b941f5e5486930f0546ce02..4fd4b930b65f148bd77ffb46f025e6829b87760f 100644 (file)
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "gamedef.h"
 #include "modchannels.h"
 #include "content/mods.h"
+#include "database/database-dummy.h"
 #include "util/numeric.h"
 #include "porting.h"
 
@@ -57,6 +58,7 @@ class TestGameDef : public IGameDef {
        scene::ISceneManager *getSceneManager() { return m_scenemgr; }
        IRollbackManager *getRollbackManager() { return m_rollbackmgr; }
        EmergeManager *getEmergeManager() { return m_emergemgr; }
+       ModMetadataDatabase *getModStorageDatabase() { return m_mod_storage_database; }
 
        scene::IAnimatedMesh *getMesh(const std::string &filename) { return NULL; }
        bool checkLocalPrivilege(const std::string &priv) { return false; }
@@ -70,7 +72,6 @@ class TestGameDef : public IGameDef {
                return testmodspec;
        }
        virtual const ModSpec* getModSpec(const std::string &modname) const { return NULL; }
-       virtual std::string getModStoragePath() const { return "."; }
        virtual bool registerModStorage(ModMetadata *meta) { return true; }
        virtual void unregisterModStorage(const std::string &name) {}
        bool joinModChannel(const std::string &channel);
@@ -91,11 +92,13 @@ class TestGameDef : public IGameDef {
        scene::ISceneManager *m_scenemgr = nullptr;
        IRollbackManager *m_rollbackmgr = nullptr;
        EmergeManager *m_emergemgr = nullptr;
+       ModMetadataDatabase *m_mod_storage_database = nullptr;
        std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
 };
 
 
 TestGameDef::TestGameDef() :
+       m_mod_storage_database(new Database_Dummy()),
        m_modchannel_mgr(new ModChannelMgr())
 {
        m_itemdef = createItemDefManager();
@@ -109,6 +112,7 @@ TestGameDef::~TestGameDef()
 {
        delete m_itemdef;
        delete m_nodedef;
+       delete m_mod_storage_database;
 }
 
 
index 35d4effb66eccaaef0767d4127b1d8c6c65fae00..f46135577821d500505554c85e5b53108feac59e 100644 (file)
@@ -56,7 +56,7 @@ void TestAddress::testIsLocalhost()
        UASSERT(!Address(172, 45, 37, 68, 0).isLocalhost());
 
        // v6
-       std::unique_ptr<IPv6AddressBytes> ipv6Bytes(new IPv6AddressBytes());
+       auto ipv6Bytes = std::make_unique<IPv6AddressBytes>();
        std::vector<u8> ipv6RawAddr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
        memcpy(ipv6Bytes->bytes, &ipv6RawAddr[0], 16);
        UASSERT(Address(ipv6Bytes.get(), 0).isLocalhost())
index 36850b00d618aff31d28495f2d49f1a2adc13464..50d2398e459e53399173a5ef8a0ba3a11ceebfa1 100644 (file)
@@ -4,3 +4,4 @@
 
 #define TEST_WORLDDIR "@TEST_WORLDDIR@"
 #define TEST_SUBGAME_PATH "@TEST_SUBGAME_PATH@"
+#define TEST_MOD_PATH "@TEST_MOD_PATH@"
index 23b7e91057a03239e68e5d6969ed80280d97ec44..04fea90d6a09072fe700cf36d321b8ca4e54404a 100644 (file)
@@ -124,7 +124,7 @@ void TestConnection::testHelpers()
        Address a(127,0,0,1, 10);
        const u16 seqnum = 34352;
 
-       con::BufferedPacket p1 = con::makePacket(a, data1,
+       con::BufferedPacketPtr p1 = con::makePacket(a, data1,
                        proto_id, peer_id, channel);
        /*
                We should now have a packet with this data:
@@ -135,10 +135,10 @@ void TestConnection::testHelpers()
                Data:
                        [7] u8 data1[0]
        */
-       UASSERT(readU32(&p1.data[0]) == proto_id);
-       UASSERT(readU16(&p1.data[4]) == peer_id);
-       UASSERT(readU8(&p1.data[6]) == channel);
-       UASSERT(readU8(&p1.data[7]) == data1[0]);
+       UASSERT(readU32(&p1->data[0]) == proto_id);
+       UASSERT(readU16(&p1->data[4]) == peer_id);
+       UASSERT(readU8(&p1->data[6]) == channel);
+       UASSERT(readU8(&p1->data[7]) == data1[0]);
 
        //infostream<<"initial data1[0]="<<((u32)data1[0]&0xff)<<std::endl;
 
index bb0e5933646613d3e5f63d58df7514c6bb128011..fec57f9feac43e385ecb5fb401e7542e8a91210c 100644 (file)
@@ -82,7 +82,7 @@ void TestEventManager::testDeregister()
 void TestEventManager::testRealEvent()
 {
        EventManager ev;
-       std::unique_ptr<EventManagerTest> emt(new EventManagerTest());
+       auto emt = std::make_unique<EventManagerTest>();
        ev.reg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get());
 
        // Put event & verify event value
@@ -93,7 +93,7 @@ void TestEventManager::testRealEvent()
 void TestEventManager::testRealEventAfterDereg()
 {
        EventManager ev;
-       std::unique_ptr<EventManagerTest> emt(new EventManagerTest());
+       auto emt = std::make_unique<EventManagerTest>();
        ev.reg(MtEvent::PLAYER_REGAIN_GROUND, EventManagerTest::eventTest, emt.get());
 
        // Put event & verify event value
diff --git a/src/unittest/test_gettext.cpp b/src/unittest/test_gettext.cpp
new file mode 100644 (file)
index 0000000..338a416
--- /dev/null
@@ -0,0 +1,43 @@
+#include "test.h"
+#include "porting.h"
+#include "gettext.h"
+
+class TestGettext : public TestBase
+{
+public:
+       TestGettext() {
+               TestManager::registerTestModule(this);
+       }
+
+       const char *getName() { return "TestGettext"; }
+
+       void runTests(IGameDef *gamedef);
+
+       void testFmtgettext();
+};
+
+static TestGettext g_test_instance;
+
+void TestGettext::runTests(IGameDef *gamedef)
+{
+       TEST(testFmtgettext);
+}
+
+// Make sure updatepo.sh does not pick up the strings
+#define dummyname fmtgettext
+
+void TestGettext::testFmtgettext()
+{
+       std::string buf = dummyname("sample text %d", 12);
+       UASSERTEQ(std::string, buf, "sample text 12");
+
+       std::string src, expect;
+       src    = "You are about to join this server with the name \"%s\".\n";
+       expect = "You are about to join this server with the name \"foo\".\n";
+       for (int i = 0; i < 20; i++) {
+               src.append("loooong text");
+               expect.append("loooong text");
+       }
+       buf = dummyname(src.c_str(), "foo");
+       UASSERTEQ(const std::string &, buf, expect);
+}
index 3484f1514fc3ee8e2c272a0ad3b2182e602d6dc2..2fb7cfcd617a70bc5a9d106658cda95072fe996a 100644 (file)
@@ -93,7 +93,9 @@ void TestIrrPtr::testRefCounting()
 
 #if defined(__clang__)
        #pragma GCC diagnostic push
-       #pragma GCC diagnostic ignored "-Wself-assign-overloaded"
+       #if __clang_major__ >= 7
+               #pragma GCC diagnostic ignored "-Wself-assign-overloaded"
+       #endif
        #pragma GCC diagnostic ignored "-Wself-move"
 #endif
 
diff --git a/src/unittest/test_lua.cpp b/src/unittest/test_lua.cpp
new file mode 100644 (file)
index 0000000..fc8f895
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2021 TurkeyMcMac, Jude Melton-Houghton <jwmhjwmh@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "test.h"
+
+extern "C" {
+#include <lua.h>
+#include <lauxlib.h>
+}
+
+class TestLua : public TestBase
+{
+public:
+       TestLua() { TestManager::registerTestModule(this); }
+       const char *getName() { return "TestLua"; }
+
+       void runTests(IGameDef *gamedef);
+
+       void testLuaDestructors();
+};
+
+static TestLua g_test_instance;
+
+void TestLua::runTests(IGameDef *gamedef)
+{
+       TEST(testLuaDestructors);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+
+       class DestructorDetector {
+               bool *did_destruct;
+       public:
+               DestructorDetector(bool *did_destruct) : did_destruct(did_destruct)
+               {
+                       *did_destruct = false;
+               }
+               ~DestructorDetector()
+               {
+                       *did_destruct = true;
+               }
+       };
+
+}
+
+void TestLua::testLuaDestructors()
+{
+       bool did_destruct = false;
+
+       lua_State *L = luaL_newstate();
+       lua_cpcall(L, [](lua_State *L) -> int {
+               DestructorDetector d(reinterpret_cast<bool*>(lua_touserdata(L, 1)));
+               luaL_error(L, "error");
+               return 0;
+       }, &did_destruct);
+       lua_close(L);
+
+       UASSERT(did_destruct);
+}
diff --git a/src/unittest/test_map.cpp b/src/unittest/test_map.cpp
new file mode 100644 (file)
index 0000000..82e55e1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+Minetest
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "test.h"
+
+#include <cstdio>
+#include "mapblock.h"
+
+class TestMap : public TestBase
+{
+public:
+       TestMap() { TestManager::registerTestModule(this); }
+       const char *getName() { return "TestMap"; }
+
+       void runTests(IGameDef *gamedef);
+
+       void testMaxMapgenLimit();
+};
+
+static TestMap g_test_instance;
+
+void TestMap::runTests(IGameDef *gamedef)
+{
+       TEST(testMaxMapgenLimit);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TestMap::testMaxMapgenLimit()
+{
+       // limit must end on a mapblock boundary
+       UASSERTEQ(int, MAX_MAP_GENERATION_LIMIT % MAP_BLOCKSIZE, MAP_BLOCKSIZE - 1);
+
+       // objectpos_over_limit should do exactly this except the last node
+       // actually spans from LIMIT-0.5 to LIMIT+0.5
+       float limit_times_bs = MAX_MAP_GENERATION_LIMIT * BS;
+       UASSERT(objectpos_over_limit(v3f(limit_times_bs-BS/2)) == false);
+       UASSERT(objectpos_over_limit(v3f(limit_times_bs)) == false);
+       UASSERT(objectpos_over_limit(v3f(limit_times_bs+BS/2)) == false);
+       UASSERT(objectpos_over_limit(v3f(limit_times_bs+BS)) == true);
+
+       UASSERT(objectpos_over_limit(v3f(-limit_times_bs+BS/2)) == false);
+       UASSERT(objectpos_over_limit(v3f(-limit_times_bs)) == false);
+       UASSERT(objectpos_over_limit(v3f(-limit_times_bs-BS/2)) == false);
+       UASSERT(objectpos_over_limit(v3f(-limit_times_bs-BS)) == true);
+
+       // blockpos_over_max_limit
+       s16 limit_block = MAX_MAP_GENERATION_LIMIT / MAP_BLOCKSIZE;
+       UASSERT(blockpos_over_max_limit(v3s16(limit_block)) == false);
+       UASSERT(blockpos_over_max_limit(v3s16(limit_block+1)) == true);
+       UASSERT(blockpos_over_max_limit(v3s16(-limit_block)) == false);
+       UASSERT(blockpos_over_max_limit(v3s16(-limit_block-1)) == true);
+}
diff --git a/src/unittest/test_mod/test_mod/init.lua b/src/unittest/test_mod/test_mod/init.lua
new file mode 100644 (file)
index 0000000..724a863
--- /dev/null
@@ -0,0 +1 @@
+-- deliberately empty
diff --git a/src/unittest/test_mod/test_mod/mod.conf b/src/unittest/test_mod/test_mod/mod.conf
new file mode 100644 (file)
index 0000000..56c64b2
--- /dev/null
@@ -0,0 +1,2 @@
+name = test_mod
+description = A mod doing nothing, to test if MINETEST_MOD_PATH is recognised
diff --git a/src/unittest/test_modmetadatadatabase.cpp b/src/unittest/test_modmetadatadatabase.cpp
new file mode 100644 (file)
index 0000000..be97fae
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+Minetest
+Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de>
+Copyright (C) 2021 TurkeyMcMac, Jude Melton-Houghton <jwmhjwmh@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+// This file is an edited copy of test_authdatabase.cpp
+
+#include "test.h"
+
+#include <algorithm>
+#include "database/database-files.h"
+#include "database/database-sqlite3.h"
+#include "filesys.h"
+
+namespace
+{
+// Anonymous namespace to create classes that are only
+// visible to this file
+//
+// These are helpers that return a *ModMetadataDatabase and
+// allow us to run the same tests on different databases and
+// database acquisition strategies.
+
+class ModMetadataDatabaseProvider
+{
+public:
+       virtual ~ModMetadataDatabaseProvider() = default;
+       virtual ModMetadataDatabase *getModMetadataDatabase() = 0;
+};
+
+class FixedProvider : public ModMetadataDatabaseProvider
+{
+public:
+       FixedProvider(ModMetadataDatabase *mod_meta_db) : mod_meta_db(mod_meta_db){};
+       virtual ~FixedProvider(){};
+       virtual ModMetadataDatabase *getModMetadataDatabase() { return mod_meta_db; };
+
+private:
+       ModMetadataDatabase *mod_meta_db;
+};
+
+class FilesProvider : public ModMetadataDatabaseProvider
+{
+public:
+       FilesProvider(const std::string &dir) : dir(dir){};
+       virtual ~FilesProvider()
+       {
+               if (mod_meta_db)
+                       mod_meta_db->endSave();
+               delete mod_meta_db;
+       }
+       virtual ModMetadataDatabase *getModMetadataDatabase()
+       {
+               if (mod_meta_db)
+                       mod_meta_db->endSave();
+               delete mod_meta_db;
+               mod_meta_db = new ModMetadataDatabaseFiles(dir);
+               mod_meta_db->beginSave();
+               return mod_meta_db;
+       };
+
+private:
+       std::string dir;
+       ModMetadataDatabase *mod_meta_db = nullptr;
+};
+
+class SQLite3Provider : public ModMetadataDatabaseProvider
+{
+public:
+       SQLite3Provider(const std::string &dir) : dir(dir){};
+       virtual ~SQLite3Provider()
+       {
+               if (mod_meta_db)
+                       mod_meta_db->endSave();
+               delete mod_meta_db;
+       }
+       virtual ModMetadataDatabase *getModMetadataDatabase()
+       {
+               if (mod_meta_db)
+                       mod_meta_db->endSave();
+               delete mod_meta_db;
+               mod_meta_db = new ModMetadataDatabaseSQLite3(dir);
+               mod_meta_db->beginSave();
+               return mod_meta_db;
+       };
+
+private:
+       std::string dir;
+       ModMetadataDatabase *mod_meta_db = nullptr;
+};
+}
+
+class TestModMetadataDatabase : public TestBase
+{
+public:
+       TestModMetadataDatabase() { TestManager::registerTestModule(this); }
+       const char *getName() { return "TestModMetadataDatabase"; }
+
+       void runTests(IGameDef *gamedef);
+       void runTestsForCurrentDB();
+
+       void testRecallFail();
+       void testCreate();
+       void testRecall();
+       void testChange();
+       void testRecallChanged();
+       void testListMods();
+       void testRemove();
+
+private:
+       ModMetadataDatabaseProvider *mod_meta_provider;
+};
+
+static TestModMetadataDatabase g_test_instance;
+
+void TestModMetadataDatabase::runTests(IGameDef *gamedef)
+{
+       // fixed directory, for persistence
+       thread_local const std::string test_dir = getTestTempDirectory();
+
+       // Each set of tests is run twice for each database type:
+       // one where we reuse the same ModMetadataDatabase object (to test local caching),
+       // and one where we create a new ModMetadataDatabase object for each call
+       // (to test actual persistence).
+
+       rawstream << "-------- Files database (same object)" << std::endl;
+
+       ModMetadataDatabase *mod_meta_db = new ModMetadataDatabaseFiles(test_dir);
+       mod_meta_provider = new FixedProvider(mod_meta_db);
+
+       runTestsForCurrentDB();
+
+       delete mod_meta_db;
+       delete mod_meta_provider;
+
+       // reset database
+       fs::RecursiveDelete(test_dir + DIR_DELIM + "mod_storage");
+
+       rawstream << "-------- Files database (new objects)" << std::endl;
+
+       mod_meta_provider = new FilesProvider(test_dir);
+
+       runTestsForCurrentDB();
+
+       delete mod_meta_provider;
+
+       rawstream << "-------- SQLite3 database (same object)" << std::endl;
+
+       mod_meta_db = new ModMetadataDatabaseSQLite3(test_dir);
+       mod_meta_provider = new FixedProvider(mod_meta_db);
+
+       runTestsForCurrentDB();
+
+       delete mod_meta_db;
+       delete mod_meta_provider;
+
+       // reset database
+       fs::DeleteSingleFileOrEmptyDirectory(test_dir + DIR_DELIM + "mod_storage.sqlite");
+
+       rawstream << "-------- SQLite3 database (new objects)" << std::endl;
+
+       mod_meta_provider = new SQLite3Provider(test_dir);
+
+       runTestsForCurrentDB();
+
+       delete mod_meta_provider;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void TestModMetadataDatabase::runTestsForCurrentDB()
+{
+       TEST(testRecallFail);
+       TEST(testCreate);
+       TEST(testRecall);
+       TEST(testChange);
+       TEST(testRecallChanged);
+       TEST(testListMods);
+       TEST(testRemove);
+       TEST(testRecallFail);
+}
+
+void TestModMetadataDatabase::testRecallFail()
+{
+       ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
+       StringMap recalled;
+       mod_meta_db->getModEntries("mod1", &recalled);
+       UASSERT(recalled.empty());
+}
+
+void TestModMetadataDatabase::testCreate()
+{
+       ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
+       StringMap recalled;
+       UASSERT(mod_meta_db->setModEntry("mod1", "key1", "value1"));
+}
+
+void TestModMetadataDatabase::testRecall()
+{
+       ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
+       StringMap recalled;
+       mod_meta_db->getModEntries("mod1", &recalled);
+       UASSERT(recalled.size() == 1);
+       UASSERT(recalled["key1"] == "value1");
+}
+
+void TestModMetadataDatabase::testChange()
+{
+       ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
+       StringMap recalled;
+       UASSERT(mod_meta_db->setModEntry("mod1", "key1", "value2"));
+}
+
+void TestModMetadataDatabase::testRecallChanged()
+{
+       ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
+       StringMap recalled;
+       mod_meta_db->getModEntries("mod1", &recalled);
+       UASSERT(recalled.size() == 1);
+       UASSERT(recalled["key1"] == "value2");
+}
+
+void TestModMetadataDatabase::testListMods()
+{
+       ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
+       UASSERT(mod_meta_db->setModEntry("mod2", "key1", "value1"));
+       std::vector<std::string> mod_list;
+       mod_meta_db->listMods(&mod_list);
+       UASSERT(mod_list.size() == 2);
+       UASSERT(std::find(mod_list.cbegin(), mod_list.cend(), "mod1") != mod_list.cend());
+       UASSERT(std::find(mod_list.cbegin(), mod_list.cend(), "mod2") != mod_list.cend());
+}
+
+void TestModMetadataDatabase::testRemove()
+{
+       ModMetadataDatabase *mod_meta_db = mod_meta_provider->getModMetadataDatabase();
+       UASSERT(mod_meta_db->removeModEntry("mod1", "key1"));
+}
diff --git a/src/unittest/test_player.cpp b/src/unittest/test_player.cpp
deleted file mode 100644 (file)
index 6990b40..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-Minetest
-Copyright (C) 2010-2016 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "test.h"
-
-#include "exceptions.h"
-#include "remoteplayer.h"
-#include "server.h"
-
-class TestPlayer : public TestBase
-{
-public:
-       TestPlayer() { TestManager::registerTestModule(this); }
-       const char *getName() { return "TestPlayer"; }
-
-       void runTests(IGameDef *gamedef);
-};
-
-static TestPlayer g_test_instance;
-
-void TestPlayer::runTests(IGameDef *gamedef)
-{
-}
index fbb76ff6a5d3cf01e1214c2c783120f1ed620daa..50305e725b5b89618044633b81cb9cf91aab04ce 100644 (file)
@@ -26,12 +26,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class FakeServer : public Server
 {
 public:
-       // clang-format off
        FakeServer() : Server("fakeworld", SubgameSpec("fakespec", "fakespec"), true,
                                        Address(), true, nullptr)
        {
        }
-       // clang-format on
 
 private:
        void SendChatMessage(session_t peer_id, const ChatMessage &message)
@@ -95,7 +93,7 @@ void TestServerShutdownState::testTrigger()
 
 void TestServerShutdownState::testTick()
 {
-       std::unique_ptr<FakeServer> fakeServer(new FakeServer());
+       auto fakeServer = std::make_unique<FakeServer>();
        Server::ShutdownState ss;
        ss.trigger(28.0f, "testtrigger", true);
        ss.tick(0.0f, fakeServer.get());
index e3edb0c32f6fadc6e32d5c209f33156f26c39b71..4c473d8b5c677faa4f72811ee37863c062287c33 100644 (file)
@@ -48,14 +48,20 @@ static TestServerModManager g_test_instance;
 void TestServerModManager::runTests(IGameDef *gamedef)
 {
        const char *saved_env_mt_subgame_path = getenv("MINETEST_SUBGAME_PATH");
+       const char *saved_env_mt_mod_path = getenv("MINETEST_MOD_PATH");
 #ifdef WIN32
        {
                std::string subgame_path("MINETEST_SUBGAME_PATH=");
                subgame_path.append(TEST_SUBGAME_PATH);
                _putenv(subgame_path.c_str());
+
+               std::string mod_path("MINETEST_MOD_PATH=");
+               mod_path.append(TEST_MOD_PATH);
+               _putenv(mod_path.c_str());
        }
 #else
        setenv("MINETEST_SUBGAME_PATH", TEST_SUBGAME_PATH, 1);
+       setenv("MINETEST_MOD_PATH", TEST_MOD_PATH, 1);
 #endif
 
        TEST(testCreation);
@@ -75,12 +81,21 @@ void TestServerModManager::runTests(IGameDef *gamedef)
                if (saved_env_mt_subgame_path)
                        subgame_path.append(saved_env_mt_subgame_path);
                _putenv(subgame_path.c_str());
+
+               std::string mod_path("MINETEST_MOD_PATH=");
+               if (saved_env_mt_mod_path)
+                       mod_path.append(saved_env_mt_mod_path);
+               _putenv(mod_path.c_str());
        }
 #else
        if (saved_env_mt_subgame_path)
                setenv("MINETEST_SUBGAME_PATH", saved_env_mt_subgame_path, 1);
        else
                unsetenv("MINETEST_SUBGAME_PATH");
+       if (saved_env_mt_mod_path)
+               setenv("MINETEST_MOD_PATH", saved_env_mt_mod_path, 1);
+       else
+               unsetenv("MINETEST_MOD_PATH");
 #endif
 }
 
@@ -89,6 +104,7 @@ void TestServerModManager::testCreation()
        std::string path = std::string(TEST_WORLDDIR) + DIR_DELIM + "world.mt";
        Settings world_config;
        world_config.set("gameid", "devtest");
+       world_config.set("load_mod_test_mod", "true");
        UASSERTEQ(bool, world_config.updateConfigFile(path.c_str()), true);
        ServerModManager sm(TEST_WORLDDIR);
 }
@@ -119,16 +135,21 @@ void TestServerModManager::testGetMods()
        UASSERTEQ(bool, mods.empty(), false);
 
        // Ensure we found basenodes mod (part of devtest)
+       // and test_mod (for testing MINETEST_MOD_PATH).
        bool default_found = false;
+       bool test_mod_found = false;
        for (const auto &m : mods) {
                if (m.name == "basenodes")
                        default_found = true;
+               if (m.name == "test_mod")
+                       test_mod_found = true;
 
                // Verify if paths are not empty
                UASSERTEQ(bool, m.path.empty(), false);
        }
 
        UASSERTEQ(bool, default_found, true);
+       UASSERTEQ(bool, test_mod_found, true);
 }
 
 void TestServerModManager::testGetModspec()
index 6d5cf334d95fb740a03056045ec48e636c65e188..620021b592aa223517cf747932c0b418715087cb 100644 (file)
@@ -97,11 +97,11 @@ void TestSocket::testIPv4Socket()
        UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0);
 
        if (address != Address(0, 0, 0, 0, port)) {
-               UASSERT(sender.getAddress().sin_addr.s_addr ==
-                               address.getAddress().sin_addr.s_addr);
+               UASSERT(sender.getAddress().s_addr ==
+                               address.getAddress().s_addr);
        } else {
-               UASSERT(sender.getAddress().sin_addr.s_addr ==
-                               Address(127, 0, 0, 1, 0).getAddress().sin_addr.s_addr);
+               UASSERT(sender.getAddress().s_addr ==
+                               Address(127, 0, 0, 1, 0).getAddress().s_addr);
        }
 }
 
@@ -128,7 +128,7 @@ void TestSocket::testIPv6Socket()
 
        socket6.Bind(address6);
 
-       try {
+       {
                socket6.Send(Address(&bytes, port), sendbuffer, sizeof(sendbuffer));
 
                sleep_ms(50);
@@ -142,10 +142,8 @@ void TestSocket::testIPv6Socket()
                }
                //FIXME: This fails on some systems
                UASSERT(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer)) == 0);
-               UASSERT(memcmp(sender.getAddress6().sin6_addr.s6_addr,
-                               Address(&bytes, 0).getAddress6().sin6_addr.s6_addr, 16) == 0);
-       } catch (SendFailedException &e) {
-               errorstream << "IPv6 support enabled but not available!"
-                                       << std::endl;
+
+               UASSERT(memcmp(sender.getAddress6().s6_addr,
+                               Address(&bytes, 0).getAddress6().s6_addr, 16) == 0);
        }
 }
index 039110d547b5bf53182ffc75eae878b694f22b4e..98a143d1f75499ee8313d0f3d5e69f89dab36eb1 100644 (file)
@@ -43,7 +43,6 @@ class TestUtilities : public TestBase {
        void testPadString();
        void testStartsWith();
        void testStrEqual();
-       void testStringTrim();
        void testStrToIntConversion();
        void testStringReplace();
        void testStringAllowed();
@@ -58,6 +57,7 @@ class TestUtilities : public TestBase {
        void testStringJoin();
        void testEulerConversion();
        void testBase64();
+       void testSanitizeDirName();
 };
 
 static TestUtilities g_test_instance;
@@ -75,7 +75,6 @@ void TestUtilities::runTests(IGameDef *gamedef)
        TEST(testPadString);
        TEST(testStartsWith);
        TEST(testStrEqual);
-       TEST(testStringTrim);
        TEST(testStrToIntConversion);
        TEST(testStringReplace);
        TEST(testStringAllowed);
@@ -90,6 +89,7 @@ void TestUtilities::runTests(IGameDef *gamedef)
        TEST(testStringJoin);
        TEST(testEulerConversion);
        TEST(testBase64);
+       TEST(testSanitizeDirName);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -190,6 +190,8 @@ void TestUtilities::testTrim()
        UASSERT(trim("dirt_with_grass") == "dirt_with_grass");
        UASSERT(trim("\n \t\r  Foo bAR  \r\n\t\t  ") == "Foo bAR");
        UASSERT(trim("\n \t\r    \r\n\t\t  ") == "");
+       UASSERT(trim("  a") == "a");
+       UASSERT(trim("a   ") == "a");
 }
 
 
@@ -255,15 +257,6 @@ void TestUtilities::testStrEqual()
 }
 
 
-void TestUtilities::testStringTrim()
-{
-       UASSERT(trim("  a") == "a");
-       UASSERT(trim("   a  ") == "a");
-       UASSERT(trim("a   ") == "a");
-       UASSERT(trim("") == "");
-}
-
-
 void TestUtilities::testStrToIntConversion()
 {
        UASSERT(mystoi("123", 0, 1000) == 123);
@@ -392,9 +385,9 @@ void TestUtilities::testIsPowerOfTwo()
        UASSERT(is_power_of_two(2) == true);
        UASSERT(is_power_of_two(3) == false);
        for (int exponent = 2; exponent <= 31; ++exponent) {
-               UASSERT(is_power_of_two((1 << exponent) - 1) == false);
-               UASSERT(is_power_of_two((1 << exponent)) == true);
-               UASSERT(is_power_of_two((1 << exponent) + 1) == false);
+               UASSERT(is_power_of_two((1U << exponent) - 1) == false);
+               UASSERT(is_power_of_two((1U << exponent)) == true);
+               UASSERT(is_power_of_two((1U << exponent) + 1) == false);
        }
        UASSERT(is_power_of_two(U32_MAX) == false);
 }
@@ -629,4 +622,17 @@ void TestUtilities::testBase64()
        UASSERT(base64_is_valid("AAA=A") == false);
        UASSERT(base64_is_valid("AAAA=A") == false);
        UASSERT(base64_is_valid("AAAAA=A") == false);
-}
\ No newline at end of file
+}
+
+
+void TestUtilities::testSanitizeDirName()
+{
+       UASSERT(sanitizeDirName("a", "~") == "a");
+       UASSERT(sanitizeDirName("  ", "~") == "__");
+       UASSERT(sanitizeDirName(" a ", "~") == "_a_");
+       UASSERT(sanitizeDirName("COM1", "~") == "~COM1");
+       UASSERT(sanitizeDirName("COM1", ":") == "_COM1");
+       UASSERT(sanitizeDirName("cOm\u00B2", "~") == "~cOm\u00B2");
+       UASSERT(sanitizeDirName("cOnIn$", "~") == "~cOnIn$");
+       UASSERT(sanitizeDirName(" cOnIn$ ", "~") == "_cOnIn$_");
+}
index 6ec0412d57c6419c30db5cee33c605633c3c1c06..a79c9778e02380e8f00e03a14e89b77e20714cab 100644 (file)
@@ -30,6 +30,7 @@ class TestVoxelArea : public TestBase
 
        void test_addarea();
        void test_pad();
+       void test_extent();
        void test_volume();
        void test_contains_voxelarea();
        void test_contains_point();
@@ -65,6 +66,7 @@ void TestVoxelArea::runTests(IGameDef *gamedef)
 {
        TEST(test_addarea);
        TEST(test_pad);
+       TEST(test_extent);
        TEST(test_volume);
        TEST(test_contains_voxelarea);
        TEST(test_contains_point);
@@ -113,10 +115,22 @@ void TestVoxelArea::test_pad()
        UASSERT(v1.MaxEdge == v3s16(-47, -9347, 969));
 }
 
+void TestVoxelArea::test_extent()
+{
+       VoxelArea v1(v3s16(-1337, -547, -789), v3s16(-147, 447, 669));
+       UASSERT(v1.getExtent() == v3s16(1191, 995, 1459));
+
+       VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
+       UASSERT(v2.getExtent() == v3s16(16, 16, 16));
+}
+
 void TestVoxelArea::test_volume()
 {
-       VoxelArea v1(v3s16(-1337, 447, -789), v3s16(-147, -9547, 669));
-       UASSERTEQ(s32, v1.getVolume(), -184657133);
+       VoxelArea v1(v3s16(-1337, -547, -789), v3s16(-147, 447, 669));
+       UASSERTEQ(s32, v1.getVolume(), 1728980655);
+
+       VoxelArea v2(v3s16(32493, -32507, 32752), v3s16(32508, -32492, 32767));
+       UASSERTEQ(s32, v2.getVolume(), 4096);
 }
 
 void TestVoxelArea::test_contains_voxelarea()
index 9c2842b43201d025869a123614e25bfe38acae32..eda7fff8980839b8d040cf54a4a7b03173db3973 100644 (file)
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #pragma once
 
+#include <utility>
 #include "debug.h"
 
 struct nullopt_t
@@ -43,18 +44,38 @@ class Optional
 public:
        Optional() noexcept {}
        Optional(nullopt_t) noexcept {}
+
        Optional(const T &value) noexcept : m_has_value(true), m_value(value) {}
+       Optional(T &&value) noexcept : m_has_value(true), m_value(std::move(value)) {}
+
        Optional(const Optional<T> &other) noexcept :
                        m_has_value(other.m_has_value), m_value(other.m_value)
+       {}
+       Optional(Optional<T> &&other) noexcept :
+                       m_has_value(other.m_has_value), m_value(std::move(other.m_value))
        {
+               other.m_has_value = false;
        }
 
-       void operator=(nullopt_t) noexcept { m_has_value = false; }
+       Optional<T> &operator=(nullopt_t) noexcept { m_has_value = false; return *this; }
 
-       void operator=(const Optional<T> &other) noexcept
+       Optional<T> &operator=(const Optional<T> &other) noexcept
        {
+               if (&other == this)
+                       return *this;
                m_has_value = other.m_has_value;
                m_value = other.m_value;
+               return *this;
+       }
+
+       Optional<T> &operator=(Optional<T> &&other) noexcept
+       {
+               if (&other == this)
+                       return *this;
+               m_has_value = other.m_has_value;
+               m_value = std::move(other.m_value);
+               other.m_has_value = false;
+               return *this;
        }
 
        T &value()
@@ -71,6 +92,13 @@ class Optional
 
        const T &value_or(const T &def) const { return m_has_value ? m_value : def; }
 
+       // Unchecked access consistent with std::optional
+       T* operator->() { return &m_value; }
+       const T* operator->() const { return &m_value; }
+
+       T& operator*() { return m_value; }
+       const T& operator*() const { return m_value; }
+
        bool has_value() const noexcept { return m_has_value; }
 
        explicit operator bool() const { return m_has_value; }
index 67bfef0c03a98ad20519550c8c79d2447700907a..bf751476f1af2ec38842fc71db63d164a7ddfa4f 100644 (file)
@@ -308,6 +308,7 @@ void SpatialAreaStore::getAreasInArea(std::vector<Area *> *result,
 SpatialAreaStore::~SpatialAreaStore()
 {
        delete m_tree;
+       delete m_storagemanager;
 }
 
 SpatialAreaStore::SpatialAreaStore()
index 334e342e095e08a9e6b05c6ea3831913c40b5250..3910c6185278acd09f0cda82e50022baf2d1c02d 100644 (file)
@@ -29,13 +29,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define CONTAINS(c, v) (std::find((c).begin(), (c).end(), (v)) != (c).end())
 
 // To disable copy constructors and assignment operations for some class
-// 'Foobar', add the macro DISABLE_CLASS_COPY(Foobar) as a private member.
+// 'Foobar', add the macro DISABLE_CLASS_COPY(Foobar) in the class definition.
 // Note this also disables copying for any classes derived from 'Foobar' as well
 // as classes having a 'Foobar' member.
 #define DISABLE_CLASS_COPY(C)        \
        C(const C &) = delete;           \
        C &operator=(const C &) = delete;
 
+// If you have used DISABLE_CLASS_COPY with a class but still want to permit moving
+// use this macro to add the default move constructors back.
+#define ALLOW_CLASS_MOVE(C)      \
+       C(C &&other) = default;      \
+       C &operator=(C &&) = default;
+
 #ifndef _MSC_VER
        #define UNUSED_ATTRIBUTE __attribute__ ((unused))
 #else
index 887258921b125757b116546d06e9f1260e3e99ba..b73763c550df4eb53c96801c0b2074c02cd89993 100644 (file)
@@ -39,7 +39,7 @@ f32 u32Tof32Slow(u32 i)
        if (exp == 0xFF) {
                // Inf/NaN
                if (imant == 0) {
-                       if (std::numeric_limits<f32>::has_infinity)     
+                       if (std::numeric_limits<f32>::has_infinity)
                                return sign ? -std::numeric_limits<f32>::infinity() :
                                        std::numeric_limits<f32>::infinity();
                        return sign ? std::numeric_limits<f32>::max() :
index 4454557a3df0da369d2fa10349781dcbdde1fb5f..63b49ac0a28d1c322b7363b08a5c46ef3dce54cd 100644 (file)
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "metricsbackend.h"
+#include "util/thread.h"
 #if USE_PROMETHEUS
 #include <prometheus/exposer.h>
 #include <prometheus/registry.h>
@@ -27,18 +28,78 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #endif
 
+/* Plain implementation */
+
+class SimpleMetricCounter : public MetricCounter
+{
+public:
+       SimpleMetricCounter() : MetricCounter(), m_counter(0.0) {}
+
+       virtual ~SimpleMetricCounter() {}
+
+       void increment(double number) override
+       {
+               MutexAutoLock lock(m_mutex);
+               m_counter += number;
+       }
+       double get() const override
+       {
+               MutexAutoLock lock(m_mutex);
+               return m_counter;
+       }
+
+private:
+       mutable std::mutex m_mutex;
+       double m_counter;
+};
+
+class SimpleMetricGauge : public MetricGauge
+{
+public:
+       SimpleMetricGauge() : MetricGauge(), m_gauge(0.0) {}
+
+       virtual ~SimpleMetricGauge() {}
+
+       void increment(double number) override
+       {
+               MutexAutoLock lock(m_mutex);
+               m_gauge += number;
+       }
+       void decrement(double number) override
+       {
+               MutexAutoLock lock(m_mutex);
+               m_gauge -= number;
+       }
+       void set(double number) override
+       {
+               MutexAutoLock lock(m_mutex);
+               m_gauge = number;
+       }
+       double get() const override
+       {
+               MutexAutoLock lock(m_mutex);
+               return m_gauge;
+       }
+
+private:
+       mutable std::mutex m_mutex;
+       double m_gauge;
+};
+
 MetricCounterPtr MetricsBackend::addCounter(
-               const std::string &name, const std::string &help_str)
+               const std::string &name, const std::string &help_str, Labels labels)
 {
-       return std::make_shared<SimpleMetricCounter>(name, help_str);
+       return std::make_shared<SimpleMetricCounter>();
 }
 
 MetricGaugePtr MetricsBackend::addGauge(
-               const std::string &name, const std::string &help_str)
+               const std::string &name, const std::string &help_str, Labels labels)
 {
-       return std::make_shared<SimpleMetricGauge>(name, help_str);
+       return std::make_shared<SimpleMetricGauge>();
 }
 
+/* Prometheus backend */
+
 #if USE_PROMETHEUS
 
 class PrometheusMetricCounter : public MetricCounter
@@ -47,13 +108,14 @@ class PrometheusMetricCounter : public MetricCounter
        PrometheusMetricCounter() = delete;
 
        PrometheusMetricCounter(const std::string &name, const std::string &help_str,
+                       MetricsBackend::Labels labels,
                        std::shared_ptr<prometheus::Registry> registry) :
                        MetricCounter(),
                        m_family(prometheus::BuildCounter()
                                                        .Name(name)
                                                        .Help(help_str)
                                                        .Register(*registry)),
-                       m_counter(m_family.Add({}))
+                       m_counter(m_family.Add(labels))
        {
        }
 
@@ -73,13 +135,14 @@ class PrometheusMetricGauge : public MetricGauge
        PrometheusMetricGauge() = delete;
 
        PrometheusMetricGauge(const std::string &name, const std::string &help_str,
+                       MetricsBackend::Labels labels,
                        std::shared_ptr<prometheus::Registry> registry) :
                        MetricGauge(),
                        m_family(prometheus::BuildGauge()
                                                        .Name(name)
                                                        .Help(help_str)
                                                        .Register(*registry)),
-                       m_gauge(m_family.Add({}))
+                       m_gauge(m_family.Add(labels))
        {
        }
 
@@ -99,8 +162,7 @@ class PrometheusMetricsBackend : public MetricsBackend
 {
 public:
        PrometheusMetricsBackend(const std::string &addr) :
-                       MetricsBackend(), m_exposer(std::unique_ptr<prometheus::Exposer>(
-                                                         new prometheus::Exposer(addr))),
+                       MetricsBackend(), m_exposer(std::make_unique<prometheus::Exposer>(addr)),
                        m_registry(std::make_shared<prometheus::Registry>())
        {
                m_exposer->RegisterCollectable(m_registry);
@@ -108,10 +170,12 @@ class PrometheusMetricsBackend : public MetricsBackend
 
        virtual ~PrometheusMetricsBackend() {}
 
-       virtual MetricCounterPtr addCounter(
-                       const std::string &name, const std::string &help_str);
-       virtual MetricGaugePtr addGauge(
-                       const std::string &name, const std::string &help_str);
+       MetricCounterPtr addCounter(
+                       const std::string &name, const std::string &help_str,
+                       Labels labels = {}) override;
+       MetricGaugePtr addGauge(
+                       const std::string &name, const std::string &help_str,
+                       Labels labels = {}) override;
 
 private:
        std::unique_ptr<prometheus::Exposer> m_exposer;
@@ -119,15 +183,15 @@ class PrometheusMetricsBackend : public MetricsBackend
 };
 
 MetricCounterPtr PrometheusMetricsBackend::addCounter(
-               const std::string &name, const std::string &help_str)
+               const std::string &name, const std::string &help_str, Labels labels)
 {
-       return std::make_shared<PrometheusMetricCounter>(name, help_str, m_registry);
+       return std::make_shared<PrometheusMetricCounter>(name, help_str, labels, m_registry);
 }
 
 MetricGaugePtr PrometheusMetricsBackend::addGauge(
-               const std::string &name, const std::string &help_str)
+               const std::string &name, const std::string &help_str, Labels labels)
 {
-       return std::make_shared<PrometheusMetricGauge>(name, help_str, m_registry);
+       return std::make_shared<PrometheusMetricGauge>(name, help_str, labels, m_registry);
 }
 
 MetricsBackend *createPrometheusMetricsBackend()
index c37306392249eda1b2f1b0032e5a39d5e30a6ab6..644c733253a0b270c7b0baf3362e96125904af4a 100644 (file)
@@ -19,8 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #pragma once
 #include <memory>
+#include <string>
+#include <utility>
 #include "config.h"
-#include "util/thread.h"
 
 class MetricCounter
 {
@@ -35,38 +36,6 @@ class MetricCounter
 
 typedef std::shared_ptr<MetricCounter> MetricCounterPtr;
 
-class SimpleMetricCounter : public MetricCounter
-{
-public:
-       SimpleMetricCounter() = delete;
-
-       virtual ~SimpleMetricCounter() {}
-
-       SimpleMetricCounter(const std::string &name, const std::string &help_str) :
-                       MetricCounter(), m_name(name), m_help_str(help_str),
-                       m_counter(0.0)
-       {
-       }
-
-       virtual void increment(double number)
-       {
-               MutexAutoLock lock(m_mutex);
-               m_counter += number;
-       }
-       virtual double get() const
-       {
-               MutexAutoLock lock(m_mutex);
-               return m_counter;
-       }
-
-private:
-       std::string m_name;
-       std::string m_help_str;
-
-       mutable std::mutex m_mutex;
-       double m_counter;
-};
-
 class MetricGauge
 {
 public:
@@ -81,47 +50,6 @@ class MetricGauge
 
 typedef std::shared_ptr<MetricGauge> MetricGaugePtr;
 
-class SimpleMetricGauge : public MetricGauge
-{
-public:
-       SimpleMetricGauge() = delete;
-
-       SimpleMetricGauge(const std::string &name, const std::string &help_str) :
-                       MetricGauge(), m_name(name), m_help_str(help_str), m_gauge(0.0)
-       {
-       }
-
-       virtual ~SimpleMetricGauge() {}
-
-       virtual void increment(double number)
-       {
-               MutexAutoLock lock(m_mutex);
-               m_gauge += number;
-       }
-       virtual void decrement(double number)
-       {
-               MutexAutoLock lock(m_mutex);
-               m_gauge -= number;
-       }
-       virtual void set(double number)
-       {
-               MutexAutoLock lock(m_mutex);
-               m_gauge = number;
-       }
-       virtual double get() const
-       {
-               MutexAutoLock lock(m_mutex);
-               return m_gauge;
-       }
-
-private:
-       std::string m_name;
-       std::string m_help_str;
-
-       mutable std::mutex m_mutex;
-       double m_gauge;
-};
-
 class MetricsBackend
 {
 public:
@@ -129,10 +57,14 @@ class MetricsBackend
 
        virtual ~MetricsBackend() {}
 
+       typedef std::initializer_list<std::pair<const std::string, std::string>> Labels;
+
        virtual MetricCounterPtr addCounter(
-                       const std::string &name, const std::string &help_str);
+                       const std::string &name, const std::string &help_str,
+                       Labels labels = {});
        virtual MetricGaugePtr addGauge(
-                       const std::string &name, const std::string &help_str);
+                       const std::string &name, const std::string &help_str,
+                       Labels labels = {});
 };
 
 #if USE_PROMETHEUS
index 7ac2e94a110544706a7d76b54fda1329acfae896..698cbc9a56d02754926e2c8f13e0ec35d55e0e6b 100755 (executable)
@@ -37,11 +37,11 @@ static void writeChunk(std::ostringstream &target, const std::string &chunk_str)
 
 std::string encodePNG(const u8 *data, u32 width, u32 height, s32 compression)
 {
-       auto file = std::ostringstream(std::ios::binary);
+       std::ostringstream file(std::ios::binary);
        file << "\x89PNG\r\n\x1a\n";
 
        {
-               auto IHDR = std::ostringstream(std::ios::binary);
+               std::ostringstream IHDR(std::ios::binary);
                IHDR << "IHDR";
                writeU32(IHDR, width);
                writeU32(IHDR, height);
@@ -51,9 +51,9 @@ std::string encodePNG(const u8 *data, u32 width, u32 height, s32 compression)
        }
 
        {
-               auto IDAT = std::ostringstream(std::ios::binary);
+               std::ostringstream IDAT(std::ios::binary);
                IDAT << "IDAT";
-               auto scanlines = std::ostringstream(std::ios::binary);
+               std::ostringstream scanlines(std::ios::binary);
                for(u32 i = 0; i < height; i++) {
                        scanlines.write("\x00", 1); // Null predictor
                        scanlines.write((const char*) data + width * 4 * i, width * 4);
index 7fc5de551d207aae26ef9ede883758cbc783b98f..245ac85bfbc028ab808e28ac5353053a331542f8 100644 (file)
@@ -22,6 +22,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes.h"
 #include "debug.h" // For assert()
 #include <cstring>
+#include <memory> // std::shared_ptr
+
+
+template<typename T> class ConstSharedPtr {
+public:
+       ConstSharedPtr(T *ptr) : ptr(ptr) {}
+       ConstSharedPtr(const std::shared_ptr<T> &ptr) : ptr(ptr) {}
+
+       const T* get() const noexcept { return ptr.get(); }
+       const T& operator*() const noexcept { return *ptr.get(); }
+       const T* operator->() const noexcept { return ptr.get(); }
+
+private:
+       std::shared_ptr<T> ptr;
+};
 
 template <typename T>
 class Buffer
@@ -40,17 +55,11 @@ class Buffer
                else
                        data = NULL;
        }
-       Buffer(const Buffer &buffer)
-       {
-               m_size = buffer.m_size;
-               if(m_size != 0)
-               {
-                       data = new T[buffer.m_size];
-                       memcpy(data, buffer.data, buffer.m_size);
-               }
-               else
-                       data = NULL;
-       }
+
+       // Disable class copy
+       Buffer(const Buffer &) = delete;
+       Buffer &operator=(const Buffer &) = delete;
+
        Buffer(Buffer &&buffer)
        {
                m_size = buffer.m_size;
@@ -81,21 +90,6 @@ class Buffer
                drop();
        }
 
-       Buffer& operator=(const Buffer &buffer)
-       {
-               if(this == &buffer)
-                       return *this;
-               drop();
-               m_size = buffer.m_size;
-               if(m_size != 0)
-               {
-                       data = new T[buffer.m_size];
-                       memcpy(data, buffer.data, buffer.m_size);
-               }
-               else
-                       data = NULL;
-               return *this;
-       }
        Buffer& operator=(Buffer &&buffer)
        {
                if(this == &buffer)
@@ -113,6 +107,18 @@ class Buffer
                return *this;
        }
 
+       void copyTo(Buffer &buffer) const
+       {
+               buffer.drop();
+               buffer.m_size = m_size;
+               if (m_size != 0) {
+                       buffer.data = new T[m_size];
+                       memcpy(buffer.data, data, m_size);
+               } else {
+                       buffer.data = nullptr;
+               }
+       }
+
        T & operator[](unsigned int i) const
        {
                return data[i];
index ceb2fef9e011933269fc7abf4b053b48a41d8011..daa7f332bd70ab94b21e6404c4b8c8e56ac6d951 100644 (file)
@@ -354,7 +354,7 @@ static size_t hash_length(SRP_HashAlgorithm alg)
                case SRP_SHA384: return SHA384_DIGEST_LENGTH;
                case SRP_SHA512: return SHA512_DIGEST_LENGTH;
                */
-               default: return -1;
+               default: return 0;
        };
 }
 // clang-format on
@@ -422,7 +422,7 @@ static SRP_Result H_nn(
 }
 
 static SRP_Result H_ns(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *n,
-       size_t len_n, const unsigned char *bytes, uint32_t len_bytes)
+       size_t len_n, const unsigned char *bytes, size_t len_bytes)
 {
        unsigned char buff[SHA512_DIGEST_LENGTH];
        size_t nbytes = len_n + len_bytes;
diff --git a/src/util/stream.h b/src/util/stream.h
new file mode 100644 (file)
index 0000000..2e61b46
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+Minetest
+Copyright (C) 2022 Minetest Authors
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+#include <iostream>
+#include <string>
+#include <functional>
+
+template<int BufferLength, typename Emitter = std::function<void(const std::string &)> >
+class StringStreamBuffer : public std::streambuf {
+public:
+       StringStreamBuffer(Emitter emitter) : m_emitter(emitter) {
+               buffer_index = 0;
+       }
+
+       int overflow(int c) {
+               push_back(c);
+               return c;
+       }
+
+       void push_back(char c) {
+               if (c == '\n' || c == '\r') {
+                       if (buffer_index)
+                               m_emitter(std::string(buffer, buffer_index));
+                       buffer_index = 0;
+               } else {
+                       buffer[buffer_index++] = c;
+                       if (buffer_index >= BufferLength) {
+                               m_emitter(std::string(buffer, buffer_index));
+                               buffer_index = 0;
+                       }
+               }
+       }
+
+       std::streamsize xsputn(const char *s, std::streamsize n) {
+               for (int i = 0; i < n; ++i)
+                       push_back(s[i]);
+               return n;
+       }
+private:
+       Emitter m_emitter;
+       char buffer[BufferLength];
+       int buffer_index;
+};
+
+class DummyStreamBuffer : public std::streambuf {
+       int overflow(int c) {
+               return c;
+       }
+       std::streamsize xsputn(const char *s, std::streamsize n) {
+               return n;
+       }
+};
index eec5ab4cddcb450eeb24b1a4cf489e8160caca9f..b805b2f78c19b28be4420b6784ea63f7d18aabdd 100644 (file)
@@ -39,8 +39,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        #include <windows.h>
 #endif
 
-#if defined(_ICONV_H_) && (defined(__FreeBSD__) || defined(__NetBSD__) || \
-       defined(__OpenBSD__) || defined(__DragonFly__))
+#ifdef __NetBSD__
+       #include <sys/param.h>
+       #if __NetBSD_Version__ <= 999001500
+               #define BSD_ICONV_USED
+       #endif
+#elif defined(_ICONV_H_) && (defined(__FreeBSD__) || defined(__OpenBSD__) || \
+       defined(__DragonFly__))
        #define BSD_ICONV_USED
 #endif
 
@@ -79,6 +84,14 @@ static bool convert(const char *to, const char *from, char *outbuf,
 #ifdef __ANDROID__
 // On Android iconv disagrees how big a wchar_t is for whatever reason
 const char *DEFAULT_ENCODING = "UTF-32LE";
+#elif defined(__NetBSD__)
+       // NetBSD does not allow "WCHAR_T" as a charset input to iconv.
+       #include <sys/endian.h>
+       #if BYTE_ORDER == BIG_ENDIAN
+       const char *DEFAULT_ENCODING = "UTF-32BE";
+       #else
+       const char *DEFAULT_ENCODING = "UTF-32LE";
+       #endif
 #else
 const char *DEFAULT_ENCODING = "WCHAR_T";
 #endif
@@ -94,7 +107,7 @@ std::wstring utf8_to_wide(const std::string &input)
        std::wstring out;
        out.resize(outbuf_size / sizeof(wchar_t));
 
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(__NetBSD__)
        SANITY_CHECK(sizeof(wchar_t) == 4);
 #endif
 
@@ -481,6 +494,7 @@ const static std::unordered_map<std::string, u32> s_named_colors = {
        {"plum",                 0xdda0dd},
        {"powderblue",           0xb0e0e6},
        {"purple",               0x800080},
+       {"rebeccapurple",        0x663399},
        {"red",                  0xff0000},
        {"rosybrown",            0xbc8f8f},
        {"royalblue",            0x4169e1},
@@ -808,9 +822,11 @@ std::wstring translate_string(const std::wstring &s)
 #endif
 }
 
-static const std::array<std::wstring, 22> disallowed_dir_names = {
+static const std::array<std::wstring, 30> disallowed_dir_names = {
        // Problematic filenames from here:
        // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#file-and-directory-names
+       // Plus undocumented values from here:
+       // https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html
        L"CON",
        L"PRN",
        L"AUX",
@@ -824,6 +840,9 @@ static const std::array<std::wstring, 22> disallowed_dir_names = {
        L"COM7",
        L"COM8",
        L"COM9",
+       L"COM\u00B2",
+       L"COM\u00B3",
+       L"COM\u00B9",
        L"LPT1",
        L"LPT2",
        L"LPT3",
@@ -833,6 +852,11 @@ static const std::array<std::wstring, 22> disallowed_dir_names = {
        L"LPT7",
        L"LPT8",
        L"LPT9",
+       L"LPT\u00B2",
+       L"LPT\u00B3",
+       L"LPT\u00B9",
+       L"CONIN$",
+       L"CONOUT$",
 };
 
 /**
@@ -840,12 +864,7 @@ static const std::array<std::wstring, 22> disallowed_dir_names = {
  */
 static const std::wstring disallowed_path_chars = L"<>:\"/\\|?*.";
 
-/**
- * Sanitize the name of a new directory. This consists of two stages:
- * 1. Check for 'reserved filenames' that can't be used on some filesystems
- *     and add a prefix to them
- * 2. Remove 'unsafe' characters from the name by replacing them with '_'
- */
+
 std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix)
 {
        std::wstring safe_name = utf8_to_wide(str);
@@ -857,7 +876,18 @@ std::string sanitizeDirName(const std::string &str, const std::string &optional_
                }
        }
 
-       for (unsigned long i = 0; i < safe_name.length(); i++) {
+       // Replace leading and trailing spaces with underscores.
+       size_t start = safe_name.find_first_not_of(L' ');
+       size_t end = safe_name.find_last_not_of(L' ');
+       if (start == std::wstring::npos || end == std::wstring::npos)
+               start = end = safe_name.size();
+       for (size_t i = 0; i < start; i++)
+               safe_name[i] = L'_';
+       for (size_t i = end + 1; i < safe_name.size(); i++)
+               safe_name[i] = L'_';
+
+       // Replace other disallowed characters with underscores
+       for (size_t i = 0; i < safe_name.length(); i++) {
                bool is_valid = true;
 
                // Unlikely, but control characters should always be blacklisted
@@ -869,8 +899,24 @@ std::string sanitizeDirName(const std::string &str, const std::string &optional_
                }
 
                if (!is_valid)
-                       safe_name[i] = '_';
+                       safe_name[i] = L'_';
        }
 
        return wide_to_utf8(safe_name);
 }
+
+
+void safe_print_string(std::ostream &os, const std::string &str)
+{
+       std::ostream::fmtflags flags = os.flags();
+       os << std::hex;
+       for (const char c : str) {
+               if (IS_ASCII_PRINTABLE_CHAR(c) || IS_UTF8_MULTB_START(c) ||
+                               IS_UTF8_MULTB_INNER(c) || c == '\n' || c == '\t') {
+                       os << c;
+               } else {
+                       os << '<' << std::setw(2) << (int)c << '>';
+               }
+       }
+       os.setf(flags);
+}
index 21f1d6877baf4d863bb4be5ade23188e54bc3dcd..aa4329f2f536d50571ce07d281acd9595c8cf322 100644 (file)
@@ -295,11 +295,11 @@ inline std::string lowercase(const std::string &str)
 inline std::string trim(const std::string &str)
 {
        size_t front = 0;
+       size_t back = str.size();
 
-       while (std::isspace(str[front]))
+       while (front < back && std::isspace(str[front]))
                ++front;
 
-       size_t back = str.size();
        while (back > front && std::isspace(str[back - 1]))
                --back;
 
@@ -410,7 +410,7 @@ DEFINE_STD_TOSTRING_FLOATINGPOINT(long double)
 template <typename T>
 inline wstring to_wstring(T val)
 {
-      return utf8_to_wide(to_string(val));
+       return utf8_to_wide(to_string(val));
 }
 }
 #endif
@@ -661,28 +661,49 @@ inline const char *bool_to_cstr(bool val)
        return val ? "true" : "false";
 }
 
+/**
+ * Converts a duration in seconds to a pretty-printed duration in
+ * days, hours, minutes and seconds.
+ *
+ * @param sec duration in seconds
+ * @return pretty-printed duration
+ */
 inline const std::string duration_to_string(int sec)
 {
+       std::ostringstream ss;
+       const char *neg = "";
+       if (sec < 0) {
+               sec = -sec;
+               neg = "-";
+       }
+       int total_sec = sec;
        int min = sec / 60;
        sec %= 60;
        int hour = min / 60;
        min %= 60;
+       int day = hour / 24;
+       hour %= 24;
+
+       if (day > 0) {
+               ss << neg << day << "d";
+               if (hour > 0 || min > 0 || sec > 0)
+                       ss << " ";
+       }
 
-       std::stringstream ss;
        if (hour > 0) {
-               ss << hour << "h";
+               ss << neg << hour << "h";
                if (min > 0 || sec > 0)
                        ss << " ";
        }
 
        if (min > 0) {
-               ss << min << "min";
+               ss << neg << min << "min";
                if (sec > 0)
                        ss << " ";
        }
 
-       if (sec > 0) {
-               ss << sec << "s";
+       if (sec > 0 || total_sec == 0) {
+               ss << neg << sec << "s";
        }
 
        return ss.str();
@@ -728,7 +749,15 @@ inline irr::core::stringw utf8_to_stringw(const std::string &input)
 /**
  * Sanitize the name of a new directory. This consists of two stages:
  * 1. Check for 'reserved filenames' that can't be used on some filesystems
- *    and prefix them
+ *    and add a prefix to them
  * 2. Remove 'unsafe' characters from the name by replacing them with '_'
  */
 std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix);
+
+/**
+ * Prints a sanitized version of a string without control characters.
+ * '\t' and '\n' are allowed, as are UTF-8 control characters (e.g. RTL).
+ * ASCII control characters are replaced with their hex encoding in angle
+ * brackets (e.g. "a\x1eb" -> "a<1e>b").
+ */
+void safe_print_string(std::ostream &os, const std::string &str);
index c555f30af26dc667c02ec372b2d6ac9a5c019cb2..f2aac37dfb3235692e33db9611c951459f8ee6d5 100644 (file)
@@ -37,7 +37,6 @@ const char *g_build_info =
 #ifndef SERVER
        "USE_GETTEXT=" STR(USE_GETTEXT) "\n"
        "USE_SOUND=" STR(USE_SOUND) "\n"
-       "USE_FREETYPE=" STR(USE_FREETYPE) "\n"
 #endif
        "STATIC_SHAREDIR=" STR(STATIC_SHAREDIR)
 #if USE_GETTEXT && defined(STATIC_LOCALEDIR)
diff --git a/textures/base/pack/no_texture.png b/textures/base/pack/no_texture.png
new file mode 100644 (file)
index 0000000..681b810
Binary files /dev/null and b/textures/base/pack/no_texture.png differ
index bfa1e4a09c99634a0b66117475903213433ab228..4484b24a79de820b1d7d478e3ba79a002a374452 100755 (executable)
@@ -19,28 +19,44 @@ builddir="$( cd "$builddir" && pwd )"
 libdir=$builddir/libs
 
 # Test which win32 compiler is present
-which i686-w64-mingw32-gcc &>/dev/null &&
-       toolchain_file=$dir/toolchain_i686-w64-mingw32.cmake
-which i686-w64-mingw32-gcc-posix &>/dev/null &&
-       toolchain_file=$dir/toolchain_i686-w64-mingw32-posix.cmake
+command -v i686-w64-mingw32-gcc >/dev/null &&
+       compiler=i686-w64-mingw32-gcc
+command -v i686-w64-mingw32-gcc-posix >/dev/null &&
+       compiler=i686-w64-mingw32-gcc-posix
 
-if [ -z "$toolchain_file" ]; then
-       echo "Unable to determine which mingw32 compiler to use"
+if [ -z "$compiler" ]; then
+       echo "Unable to determine which MinGW compiler to use"
        exit 1
 fi
+toolchain_file=$dir/toolchain_${compiler/-gcc/}.cmake
 echo "Using $toolchain_file"
 
-irrlicht_version=1.9.0mt3
-ogg_version=1.3.4
+# Try to find runtime DLLs in various paths (varies by distribution, sigh)
+tmp=$(dirname "$(command -v $compiler)")/..
+runtime_dlls=
+for name in lib{gcc_,stdc++-,winpthread-}'*'.dll; do
+       for dir in $tmp/i686-w64-mingw32/{bin,lib} $tmp/lib/gcc/i686-w64-mingw32/*; do
+               [ -d "$dir" ] || continue
+               file=$(echo $dir/$name)
+               [ -f "$file" ] && { runtime_dlls+="$file;"; break; }
+       done
+done
+[ -z "$runtime_dlls" ] &&
+       echo "The compiler runtime DLLs could not be found, they might be missing in the final package."
+
+# Get stuff
+irrlicht_version=1.9.0mt5
+ogg_version=1.3.5
+openal_version=1.21.1
 vorbis_version=1.3.7
-curl_version=7.76.1
+curl_version=7.81.0
 gettext_version=0.20.1
-freetype_version=2.10.4
-sqlite3_version=3.35.5
+freetype_version=2.11.1
+sqlite3_version=3.37.2
 luajit_version=2.1.0-beta3
 leveldb_version=1.23
 zlib_version=1.2.11
-zstd_version=1.4.9
+zstd_version=1.5.2
 
 mkdir -p $libdir
 
@@ -63,29 +79,33 @@ download () {
        fi
 }
 
-# Get stuff
+# 'dw2' just points to rebuilt versions after a toolchain change
+# this distinction should be gotten rid of next time
+
 cd $libdir
 download "https://github.com/minetest/irrlicht/releases/download/$irrlicht_version/win32.zip" irrlicht-$irrlicht_version.zip
-download "http://minetest.kitsunemimi.pw/zlib-$zlib_version-win32.zip"
+download "http://minetest.kitsunemimi.pw/dw2/zlib-$zlib_version-win32.zip"
 download "http://minetest.kitsunemimi.pw/zstd-$zstd_version-win32.zip"
 download "http://minetest.kitsunemimi.pw/libogg-$ogg_version-win32.zip"
-download "http://minetest.kitsunemimi.pw/libvorbis-$vorbis_version-win32.zip"
+download "http://minetest.kitsunemimi.pw/dw2/libvorbis-$vorbis_version-win32.zip"
 download "http://minetest.kitsunemimi.pw/curl-$curl_version-win32.zip"
-download "http://minetest.kitsunemimi.pw/gettext-$gettext_version-win32.zip"
+download "http://minetest.kitsunemimi.pw/dw2/gettext-$gettext_version-win32.zip"
 download "http://minetest.kitsunemimi.pw/freetype2-$freetype_version-win32.zip" freetype-$freetype_version.zip
 download "http://minetest.kitsunemimi.pw/sqlite3-$sqlite3_version-win32.zip"
-download "http://minetest.kitsunemimi.pw/luajit-$luajit_version-win32.zip"
-download "http://minetest.kitsunemimi.pw/libleveldb-$leveldb_version-win32.zip" leveldb-$leveldb_version.zip
-download "http://minetest.kitsunemimi.pw/openal_stripped.zip" '' unzip_nofolder
+download "http://minetest.kitsunemimi.pw/dw2/luajit-$luajit_version-win32.zip"
+download "http://minetest.kitsunemimi.pw/dw2/libleveldb-$leveldb_version-win32.zip" leveldb-$leveldb_version.zip
+download "http://minetest.kitsunemimi.pw/openal-soft-$openal_version-win32.zip"
 
 # Set source dir, downloading Minetest as needed
 if [ -n "$EXISTING_MINETEST_DIR" ]; then
        sourcedir="$( cd "$EXISTING_MINETEST_DIR" && pwd )"
 else
+       cd $builddir
        sourcedir=$PWD/$CORE_NAME
        [ -d $CORE_NAME ] && { pushd $CORE_NAME; git pull; popd; } || \
                git clone -b $CORE_BRANCH $CORE_GIT $CORE_NAME
        if [ -z "$NO_MINETEST_GAME" ]; then
+               cd $sourcedir
                [ -d games/$GAME_NAME ] && { pushd games/$GAME_NAME; git pull; popd; } || \
                        git clone -b $GAME_BRANCH $GAME_GIT games/$GAME_NAME
        fi
@@ -96,23 +116,21 @@ git_hash=$(cd $sourcedir && git rev-parse --short HEAD)
 # Build the thing
 cd $builddir
 [ -d build ] && rm -rf build
-mkdir build
-cd build
 
 irr_dlls=$(echo $libdir/irrlicht/lib/*.dll | tr ' ' ';')
 vorbis_dlls=$(echo $libdir/libvorbis/bin/libvorbis{,file}-*.dll | tr ' ' ';')
 gettext_dlls=$(echo $libdir/gettext/bin/lib{intl,iconv}-*.dll | tr ' ' ';')
 
-cmake -S $sourcedir -B . \
+cmake -S $sourcedir -B build \
        -DCMAKE_TOOLCHAIN_FILE=$toolchain_file \
        -DCMAKE_INSTALL_PREFIX=/tmp \
        -DVERSION_EXTRA=$git_hash \
        -DBUILD_CLIENT=1 -DBUILD_SERVER=0 \
+       -DEXTRA_DLL="$runtime_dlls" \
        \
        -DENABLE_SOUND=1 \
        -DENABLE_CURL=1 \
        -DENABLE_GETTEXT=1 \
-       -DENABLE_FREETYPE=1 \
        -DENABLE_LEVELDB=1 \
        \
        -DCMAKE_PREFIX_PATH=$libdir/irrlicht \
@@ -138,15 +156,15 @@ cmake -S $sourcedir -B . \
        -DVORBIS_DLL="$vorbis_dlls" \
        -DVORBISFILE_LIBRARY=$libdir/libvorbis/lib/libvorbisfile.dll.a \
        \
-       -DOPENAL_INCLUDE_DIR=$libdir/openal_stripped/include/AL \
-       -DOPENAL_LIBRARY=$libdir/openal_stripped/lib/libOpenAL32.dll.a \
-       -DOPENAL_DLL=$libdir/openal_stripped/bin/OpenAL32.dll \
+       -DOPENAL_INCLUDE_DIR=$libdir/openal/include/AL \
+       -DOPENAL_LIBRARY=$libdir/openal/lib/libOpenAL32.dll.a \
+       -DOPENAL_DLL=$libdir/openal/bin/OpenAL32.dll \
        \
        -DCURL_DLL=$libdir/curl/bin/libcurl-4.dll \
        -DCURL_INCLUDE_DIR=$libdir/curl/include \
        -DCURL_LIBRARY=$libdir/curl/lib/libcurl.dll.a \
        \
-       -DGETTEXT_MSGFMT=`which msgfmt` \
+       -DGETTEXT_MSGFMT=`command -v msgfmt` \
        -DGETTEXT_DLL="$gettext_dlls" \
        -DGETTEXT_INCLUDE_DIR=$libdir/gettext/include \
        -DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a \
@@ -164,9 +182,9 @@ cmake -S $sourcedir -B . \
        -DLEVELDB_LIBRARY=$libdir/leveldb/lib/libleveldb.dll.a \
        -DLEVELDB_DLL=$libdir/leveldb/bin/libleveldb.dll
 
-make -j$(nproc)
+cmake --build build -j$(nproc)
 
-[ -z "$NO_PACKAGE" ] && make package
+[ -z "$NO_PACKAGE" ] && cmake --build build --target package
 
 exit 0
 # EOF
index 5acb43b73317067e2762e6b46e79709ad2df4480..f367e68a538c1787ed708366af8470f8fe1412bf 100755 (executable)
@@ -19,28 +19,44 @@ builddir="$( cd "$builddir" && pwd )"
 libdir=$builddir/libs
 
 # Test which win64 compiler is present
-which x86_64-w64-mingw32-gcc &>/dev/null &&
-       toolchain_file=$dir/toolchain_x86_64-w64-mingw32.cmake
-which x86_64-w64-mingw32-gcc-posix &>/dev/null &&
-       toolchain_file=$dir/toolchain_x86_64-w64-mingw32-posix.cmake
+command -v x86_64-w64-mingw32-gcc >/dev/null &&
+       compiler=x86_64-w64-mingw32-gcc
+command -v x86_64-w64-mingw32-gcc-posix >/dev/null &&
+       compiler=x86_64-w64-mingw32-gcc-posix
 
-if [ -z "$toolchain_file" ]; then
-       echo "Unable to determine which mingw32 compiler to use"
+if [ -z "$compiler" ]; then
+       echo "Unable to determine which MinGW compiler to use"
        exit 1
 fi
+toolchain_file=$dir/toolchain_${compiler/-gcc/}.cmake
 echo "Using $toolchain_file"
 
-irrlicht_version=1.9.0mt3
-ogg_version=1.3.4
+# Try to find runtime DLLs in various paths (varies by distribution, sigh)
+tmp=$(dirname "$(command -v $compiler)")/..
+runtime_dlls=
+for name in lib{gcc_,stdc++-,winpthread-}'*'.dll; do
+       for dir in $tmp/x86_64-w64-mingw32/{bin,lib} $tmp/lib/gcc/x86_64-w64-mingw32/*; do
+               [ -d "$dir" ] || continue
+               file=$(echo $dir/$name)
+               [ -f "$file" ] && { runtime_dlls+="$file;"; break; }
+       done
+done
+[ -z "$runtime_dlls" ] &&
+       echo "The compiler runtime DLLs could not be found, they might be missing in the final package."
+
+# Get stuff
+irrlicht_version=1.9.0mt5
+ogg_version=1.3.5
+openal_version=1.21.1
 vorbis_version=1.3.7
-curl_version=7.76.1
+curl_version=7.81.0
 gettext_version=0.20.1
-freetype_version=2.10.4
-sqlite3_version=3.35.5
+freetype_version=2.11.1
+sqlite3_version=3.37.2
 luajit_version=2.1.0-beta3
 leveldb_version=1.23
 zlib_version=1.2.11
-zstd_version=1.4.9
+zstd_version=1.5.2
 
 mkdir -p $libdir
 
@@ -63,7 +79,6 @@ download () {
        fi
 }
 
-# Get stuff
 cd $libdir
 download "https://github.com/minetest/irrlicht/releases/download/$irrlicht_version/win64.zip" irrlicht-$irrlicht_version.zip
 download "http://minetest.kitsunemimi.pw/zlib-$zlib_version-win64.zip"
@@ -76,16 +91,18 @@ download "http://minetest.kitsunemimi.pw/freetype2-$freetype_version-win64.zip"
 download "http://minetest.kitsunemimi.pw/sqlite3-$sqlite3_version-win64.zip"
 download "http://minetest.kitsunemimi.pw/luajit-$luajit_version-win64.zip"
 download "http://minetest.kitsunemimi.pw/libleveldb-$leveldb_version-win64.zip" leveldb-$leveldb_version.zip
-download "http://minetest.kitsunemimi.pw/openal_stripped64.zip" 'openal_stripped.zip' unzip_nofolder
+download "http://minetest.kitsunemimi.pw/openal-soft-$openal_version-win64.zip"
 
 # Set source dir, downloading Minetest as needed
 if [ -n "$EXISTING_MINETEST_DIR" ]; then
        sourcedir="$( cd "$EXISTING_MINETEST_DIR" && pwd )"
 else
+       cd $builddir
        sourcedir=$PWD/$CORE_NAME
        [ -d $CORE_NAME ] && { pushd $CORE_NAME; git pull; popd; } || \
                git clone -b $CORE_BRANCH $CORE_GIT $CORE_NAME
        if [ -z "$NO_MINETEST_GAME" ]; then
+               cd $sourcedir
                [ -d games/$GAME_NAME ] && { pushd games/$GAME_NAME; git pull; popd; } || \
                        git clone -b $GAME_BRANCH $GAME_GIT games/$GAME_NAME
        fi
@@ -96,23 +113,21 @@ git_hash=$(cd $sourcedir && git rev-parse --short HEAD)
 # Build the thing
 cd $builddir
 [ -d build ] && rm -rf build
-mkdir build
-cd build
 
 irr_dlls=$(echo $libdir/irrlicht/lib/*.dll | tr ' ' ';')
 vorbis_dlls=$(echo $libdir/libvorbis/bin/libvorbis{,file}-*.dll | tr ' ' ';')
 gettext_dlls=$(echo $libdir/gettext/bin/lib{intl,iconv}-*.dll | tr ' ' ';')
 
-cmake -S $sourcedir -B . \
+cmake -S $sourcedir -B build \
        -DCMAKE_TOOLCHAIN_FILE=$toolchain_file \
        -DCMAKE_INSTALL_PREFIX=/tmp \
        -DVERSION_EXTRA=$git_hash \
        -DBUILD_CLIENT=1 -DBUILD_SERVER=0 \
+       -DEXTRA_DLL="$runtime_dlls" \
        \
        -DENABLE_SOUND=1 \
        -DENABLE_CURL=1 \
        -DENABLE_GETTEXT=1 \
-       -DENABLE_FREETYPE=1 \
        -DENABLE_LEVELDB=1 \
        \
        -DCMAKE_PREFIX_PATH=$libdir/irrlicht \
@@ -138,15 +153,15 @@ cmake -S $sourcedir -B . \
        -DVORBIS_DLL="$vorbis_dlls" \
        -DVORBISFILE_LIBRARY=$libdir/libvorbis/lib/libvorbisfile.dll.a \
        \
-       -DOPENAL_INCLUDE_DIR=$libdir/openal_stripped/include/AL \
-       -DOPENAL_LIBRARY=$libdir/openal_stripped/lib/libOpenAL32.dll.a \
-       -DOPENAL_DLL=$libdir/openal_stripped/bin/OpenAL32.dll \
+       -DOPENAL_INCLUDE_DIR=$libdir/openal/include/AL \
+       -DOPENAL_LIBRARY=$libdir/openal/lib/libOpenAL32.dll.a \
+       -DOPENAL_DLL=$libdir/openal/bin/OpenAL32.dll \
        \
        -DCURL_DLL=$libdir/curl/bin/libcurl-4.dll \
        -DCURL_INCLUDE_DIR=$libdir/curl/include \
        -DCURL_LIBRARY=$libdir/curl/lib/libcurl.dll.a \
        \
-       -DGETTEXT_MSGFMT=`which msgfmt` \
+       -DGETTEXT_MSGFMT=`command -v msgfmt` \
        -DGETTEXT_DLL="$gettext_dlls" \
        -DGETTEXT_INCLUDE_DIR=$libdir/gettext/include \
        -DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a \
@@ -164,9 +179,9 @@ cmake -S $sourcedir -B . \
        -DLEVELDB_LIBRARY=$libdir/leveldb/lib/libleveldb.dll.a \
        -DLEVELDB_DLL=$libdir/leveldb/bin/libleveldb.dll
 
-make -j$(nproc)
+cmake --build build -j$(nproc)
 
-[ -z "$NO_PACKAGE" ] && make package
+[ -z "$NO_PACKAGE" ] && cmake --build build --target package
 
 exit 0
 # EOF
index ba77cd645662b72ba244fd3144cef633014cc579..88349b852af6ee05b607cf6f309bfbedcac3bb01 100755 (executable)
@@ -1,8 +1,10 @@
 #! /bin/bash -e
 
-mkdir cmakebuild
-cd cmakebuild
-cmake -DCMAKE_BUILD_TYPE=Debug \
-       -DRUN_IN_PLACE=TRUE -DENABLE_GETTEXT=TRUE \
-       -DBUILD_SERVER=TRUE ${CMAKE_FLAGS} ..
-make -j2
+cmake -B build \
+       -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Debug} \
+       -DRUN_IN_PLACE=TRUE \
+       -DENABLE_GETTEXT=${CMAKE_ENABLE_GETTEXT:-TRUE} \
+       -DBUILD_SERVER=${CMAKE_BUILD_SERVER:-TRUE} \
+       ${CMAKE_FLAGS}
+
+cmake --build build --parallel $(($(nproc) + 1))
index edfd574cd6d5473b37350ab04e8826437fbd1b53..f3e4a5559ae497eb772d1ada07fee95521c44473 100755 (executable)
@@ -8,6 +8,6 @@ cmake .. \
        -DCMAKE_INSTALL_PREFIX=/usr/local \
        -DCMAKE_BUILD_TYPE=Release \
        -DENABLE_TESTING=0
-make -j2
+make -j$(nproc)
 sudo make install
 
index bb4e99fef8e3f27b465b6d35820ebb5353ccf607..e678cf3b9dcb98674e5672c4fea363ca8d1c814f 100755 (executable)
@@ -1,17 +1,13 @@
 #! /bin/bash -eu
 
-mkdir -p cmakebuild
-cd cmakebuild
-cmake -DCMAKE_BUILD_TYPE=Debug \
+cmake -B build -DCMAKE_BUILD_TYPE=Debug \
        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
        -DRUN_IN_PLACE=TRUE \
        -DENABLE_{GETTEXT,SOUND}=FALSE \
-       -DBUILD_SERVER=TRUE ..
-make GenerateVersion
-
-cd ..
+       -DBUILD_SERVER=TRUE
+cmake --build build --target GenerateVersion
 
 ./util/ci/run-clang-tidy.py \
-       -clang-tidy-binary=clang-tidy-9 -p cmakebuild \
+       -clang-tidy-binary=clang-tidy-9 -p build \
        -quiet -config="$(cat .clang-tidy)" \
        'src/.*'
index 88bed9ed49628b8e506a4fe24337f0d8c5dea572..82529c712a7584f5c2edd1d387b1edc787db45f8 100644 (file)
@@ -7,19 +7,18 @@ install_linux_deps() {
                libhiredis-dev libogg-dev libgmp-dev libvorbis-dev libopenal-dev \
                gettext libpq-dev libleveldb-dev libcurl4-openssl-dev libzstd-dev)
 
-       if [[ "$1" == "--old-irr" ]]; then
+       if [[ "$1" == "--no-irr" ]]; then
+               shift
+       elif [[ "$1" == "--old-irr" ]]; then
                shift
                pkgs+=(libirrlicht-dev)
        else
-               wget "https://github.com/minetest/irrlicht/releases/download/1.9.0mt3/ubuntu-bionic.tar.gz"
+               wget "https://github.com/minetest/irrlicht/releases/download/1.9.0mt5/ubuntu-bionic.tar.gz"
                sudo tar -xaf ubuntu-bionic.tar.gz -C /usr/local
        fi
 
        sudo apt-get update
        sudo apt-get install -y --no-install-recommends ${pkgs[@]} "$@"
-
-       # workaround for bug with Github Actions' ubuntu-18.04 image
-       sudo apt-get remove -y libgcc-11-dev gcc-11 || :
 }
 
 # Mac OSX build only
diff --git a/util/generate-texture-normals.sh b/util/generate-texture-normals.sh
deleted file mode 100755 (executable)
index 6279dfa..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-#!/bin/bash
-
-# This script generates normalmaps using The GIMP to do the heavy lifting.
-# give any unrecognized switch (say, -h) for usage info.
-
-rm /tmp/normals_filelist.txt
-
-numprocs=6
-
-skiptools=false
-skipinventory=false
-invresolution=64
-dryrun=false
-pattern="*.png *.jpg"
-
-filter=0
-scale=8
-wrap=0
-heightsource=0
-conversion=0
-invertx=0
-inverty=0
-
-while test -n "$1"; do
-       case "$1" in
-               --scale|-s)
-                       if [ -z "$2" ] ; then echo "Missing scale parameter"; exit 1; fi
-                       scale=$2
-                       shift
-                       shift
-                       ;;
-               --pattern|-p)
-                       if [ -z "$2" ] ; then echo "Missing pattern parameter"; exit 1; fi
-                       pattern=$2
-                       shift
-                       shift
-                       ;;
-               --skiptools|-t)
-                       skiptools=true
-                       shift
-                       ;;
-               --skipinventory|-i)
-                       if [[ $2 =~ ^[0-9]+$ ]]; then
-                               invresolution=$2
-                               shift
-                       fi
-                       skipinventory=true
-                       shift
-                       ;;
-               --filter|-f)
-                       if [ -z "$2" ] ; then echo "Missing filter parameter"; exit 1; fi
-
-                       case "$2" in
-                               sobel3|1)
-                                       filter=1
-                                       ;;
-                               sobel5|2)
-                                       filter=2
-                                       ;;
-                               prewitt3|3)
-                                       filter=3
-                                       ;;
-                               prewitt5|4)
-                                       filter=4
-                                       ;;
-                               3x3|5)
-                                       filter=5
-                                       ;;
-                               5x5|6)
-                                       filter=6
-                                       ;;
-                               7x7|7)
-                                       filter=7
-                                       ;;
-                               9x9|8)
-                                       filter=8
-                                       ;;
-                               *)
-                                       filter=0
-                                       ;;
-                       esac
-
-                       shift
-                       shift
-                       ;;
-               --heightalpha|-a)
-                       heightsource=1
-                       shift
-                       ;;
-               --conversion|-c)
-                               if [ -z "$2" ] ; then echo "Missing conversion parameter"; exit 1; fi
-
-                               case "$2" in
-                                       biased|1)
-                                               conversion=1
-                                               ;;
-                                       red|2)
-                                               conversion=2
-                                               ;;
-                                       green|3)
-                                               conversion=3
-                                               ;;
-                                       blue|4)
-                                               conversion=4
-                                               ;;
-                                       maxrgb|5)
-                                               conversion=5
-                                               ;;
-                                       minrgb|6)
-                                               conversion=6
-                                               ;;
-                                       colorspace|7)
-                                               conversion=7
-                                               ;;
-                                       normalize-only|8)
-                                               conversion=8
-                                               ;;
-                                       heightmap|9)
-                                               conversion=9
-                                               ;;
-                                       *)
-                                               conversion=0
-                                               ;;
-                       esac
-
-                       shift
-                       shift
-                       ;;
-               --wrap|-w)
-                       wrap=1
-                       shift
-                       ;;
-               --invertx|-x)
-                       invertx=1
-                       shift
-                       ;;
-               --inverty|-y)
-                       inverty=1
-                       shift
-                       ;;
-               --dryrun|-d)
-                       dryrun=true
-                       shift
-                       ;;
-               *)
-                       echo -e "\nUsage:\n"
-                       echo "`basename $0` [--scale|-s <value>] [--filter|-f <string>]"
-                       echo " [--wrap|-w] [--heightalpha|-a] [--invertx|-x] [--inverty|-y]"
-                       echo " [--conversion|-c <string>] [--skiptools|-t] [--skipinventory|-i [<value>]]"
-                       echo " [--dryrun|-d] [--pattern|-p <pattern>]"
-                       echo -e "\nDefaults to a scale of 8, checking all files in the current directory, and not"
-                       echo "skipping apparent tools or inventory images.  Filter, if specified, may be one"
-                       echo "of: sobel3, sobel5, prewitt3, prewitt5, 3x3, 5x5, 7x7, or 9x9, or a value 1"
-                       echo "through 8 (1=sobel3, 2=sobel5, etc.). Defaults to 0 (four-sample).  The height"
-                       echo "source is taken from the image's alpha channel if heightalpha is specified.\n"
-                       echo ""
-                       echo "If inventory skip is specified, an optional resolution may also be included"
-                       echo "(default is 64).  Conversion can be one of: biased, red, green, blue, maxrgb,"
-                       echo "minrgb, colorspace, normalize-only, heightmap or a value from 1 to 9"
-                       echo "corresponding respectively to those keywords.  Defaults to 0 (simple"
-                       echo "normalize) if not specified.  Wrap, if specified, enables wrapping of the"
-                       echo "normalmap around the edges of the texture (defaults to no).  Invert X/Y"
-                       echo "reverses the calculated gradients  for the X and/or Y dimensions represented"
-                       echo "by the normalmap (both default to non-inverted)."
-                       echo ""
-                       echo "The pattern, can be an escaped pattern string such as \*apple\* or"
-                       echo "default_\*.png or similar (defaults to all PNG and JPG images in the current"
-                       echo "directory that do not contain \"_normal\" or \"_specular\" in their filenames)."
-                       echo ""
-                       echo "If set for dry-run, the actions this script will take will be printed, but no"
-                       echo "images will be generated.  Passing an invalid value to a switch will generally"
-                       echo "cause that switch to revert to its default value."
-                       echo ""
-                       exit 1
-                       ;;
-       esac
-done
-
-echo -e "\nProcessing files based on pattern \"$pattern\" ..."
-
-normalMap()
-{
-       out=`echo "$1" | sed 's/.png/_normal.png/' | sed 's/.jpg/_normal.png/'`
-
-       echo "Launched process to generate normalmap: \"$1\" --> \"$out\"" >&2
-
-       gimp -i -b "
-               (define
-                       (normalMap-fbx-conversion fileName newFileName filter nscale wrap heightsource conversion invertx inverty)
-                       (let*
-                               (
-                                       (image (car (gimp-file-load RUN-NONINTERACTIVE fileName fileName)))
-                                       (drawable (car (gimp-image-get-active-layer image)))
-                                       (drawable (car (gimp-image-flatten image)))
-                               )
-                               (if (> (car (gimp-drawable-type drawable)) 1)
-                                       (gimp-convert-rgb image) ()
-                               )
-
-                               (plug-in-normalmap 
-                                       RUN-NONINTERACTIVE
-                                       image
-                                       drawable
-                                       filter
-                                       0.0
-                                       nscale
-                                       wrap
-                                       heightsource
-                                       0
-                                       conversion
-                                       0
-                                       invertx
-                                       inverty
-                                       0
-                                       0.0
-                                       drawable)
-                               (gimp-file-save RUN-NONINTERACTIVE image drawable newFileName newFileName)
-                               (gimp-image-delete image)
-                       )
-               )
-               (normalMap-fbx-conversion \"$1\" \"$out\" $2 $3 $4 $5 $6 $7 $8)" -b '(gimp-quit 0)'
-}
-
-export -f normalMap
-
-for file in `ls $pattern |grep -v "_normal.png"|grep -v "_specular"` ; do
-
-       invtest=`file "$file" |grep "$invresolution x $invresolution"`
-       if $skipinventory && [ -n "$invtest" ] ; then
-               echo "Skipped presumed "$invresolution"px inventory image: $file" >&2
-               continue
-       fi
-
-       tooltest=`echo "$file" \
-               | grep -v "_tool" \
-               | grep -v "_shovel" \
-               | grep -v "_pick" \
-               | grep -v "_axe" \
-               | grep -v "_sword" \
-               | grep -v "_hoe" \
-               | grep -v "bucket_"`
-
-       if $skiptools && [ -z "$tooltest" ] ; then
-               echo "Skipped presumed tool image: $file" >&2
-               continue
-       fi
-
-       if $dryrun ; then
-               echo "Would have generated a normalmap for $file" >&2
-               continue
-       else
-               echo \"$file\" $filter $scale $wrap $heightsource $conversion $invertx $inverty
-       fi
-done | xargs -P $numprocs -n 8 -I{} bash -c normalMap\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}
-
index 9fb894a3032a4bb2e8abbd976d545c926172c84f..5ffc044e06bc099d153df8381f7ccc6897e1185c 100755 (executable)
@@ -20,7 +20,7 @@ waitfor () {
 }
 
 gdbrun () {
-       gdb -q -ex 'set confirm off' -ex 'r' -ex 'bt' -ex 'quit' --args "$@"
+       gdb -q -batch -ex 'set confirm off' -ex 'r' -ex 'bt' --args "$@"
 }
 
 [ -e $minetest ] || { echo "executable $minetest missing"; exit 1; }
@@ -33,17 +33,27 @@ printf '%s\n' >$testspath/client1.conf \
        enable_{sound,minimap,shaders}=false
 
 printf '%s\n' >$testspath/server.conf \
-       max_block_send_distance=1
+       max_block_send_distance=1 devtest_unittests_autostart=true
 
 cat >$worldpath/worldmods/test/init.lua <<"LUA"
 core.after(0, function()
        io.close(io.open(core.get_worldpath() .. "/startup", "w"))
 end)
-core.register_on_joinplayer(function(player)
-       io.close(io.open(core.get_worldpath() .. "/player_joined", "w"))
+local function callback(test_ok)
+       if not test_ok then
+               io.close(io.open(core.get_worldpath() .. "/test_failure", "w"))
+       end
+       io.close(io.open(core.get_worldpath() .. "/done", "w"))
        core.request_shutdown("", false, 2)
-end)
+end
+if core.settings:get_bool("devtest_unittests_autostart") then
+       unittests.on_finished = callback
+else
+       core.register_on_joinplayer(function() callback(true) end)
+end
 LUA
+printf '%s\n' >$worldpath/worldmods/test/mod.conf \
+       name=test optional_depends=unittests
 
 echo "Starting server"
 gdbrun $minetest --server --config $conf_server --world $worldpath --gameid $gameid 2>&1 | sed -u 's/^/(server) /' &
@@ -51,10 +61,14 @@ waitfor $worldpath/startup
 
 echo "Starting client"
 gdbrun $minetest --config $conf_client1 --go --address 127.0.0.1 2>&1 | sed -u 's/^/(client) /' &
-waitfor $worldpath/player_joined
+waitfor $worldpath/done
 
 echo "Waiting for client and server to exit"
 wait
 
+if [ -f $worldpath/test_failure ]; then
+       echo "There were test failures."
+       exit 1
+fi
 echo "Success"
 exit 0
index dbcb16fdedd832f54eacef274c8c116d190067f5..23e2c61e976599e3607c1d074f2782ccd5802173 100755 (executable)
@@ -13,7 +13,7 @@ abort() {
 # this script is. Relative paths are fine for us so we can just
 # use the following trick (works both for manual invocations and for
 # script found from PATH)
-scriptisin="$(dirname "$(which "$0")")"
+scriptisin="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 
 # The script is executed from the parent of po/, which is also the
 # parent of the script directory and of the src/ directory.
@@ -61,6 +61,7 @@ xgettext --package-name=minetest \
        --keyword=wstrgettext \
        --keyword=core.gettext \
        --keyword=showTranslatedStatusText \
+       --keyword=fmtgettext \
        --output $potfile \
        --from-code=utf-8 \
        `find src/ -name '*.cpp' -o -name '*.h'` \
index d954c7597b388f40b7964ae024894592fecfd3e5..40e1956f3e8343ca6bbd87fc86a5d5bbe3fca207 100644 (file)
@@ -422,8 +422,8 @@ do
                                        t:add(f_pointed_under_y, buffer(13,2))
                                        t:add(f_pointed_under_z, buffer(15,2))
                                        t:add(f_pointed_above_x, buffer(17,2))
-                                       t:add(f_pointed_above_x, buffer(19,2))
-                                       t:add(f_pointed_above_x, buffer(21,2))
+                                       t:add(f_pointed_above_y, buffer(19,2))
+                                       t:add(f_pointed_above_z, buffer(21,2))
                                elseif ptype == 2 then -- Object
                                        t:add(f_pointed_object_id, buffer(11,2))
                                end