diff -Nru minetest-5.1.1/build/android/build.gradle minetest-5.2.0/build/android/build.gradle --- minetest-5.1.1/build/android/build.gradle 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/build/android/build.gradle 2020-04-05 17:53:12.000000000 +0000 @@ -28,7 +28,7 @@ buildToolsVersion '29.0.2' defaultConfig { - versionCode 25 + versionCode 26 versionName "${System.env.VERSION_STR}.${versionCode}" minSdkVersion 14 targetSdkVersion 29 diff -Nru minetest-5.1.1/build/android/jni/Android.mk minetest-5.2.0/build/android/jni/Android.mk --- minetest-5.1.1/build/android/jni/Android.mk 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/build/android/jni/Android.mk 2020-04-05 17:53:12.000000000 +0000 @@ -178,12 +178,20 @@ jni/src/filesys.cpp \ jni/src/genericobject.cpp \ jni/src/gettext.cpp \ + jni/src/gui/guiAnimatedImage.cpp \ + jni/src/gui/guiBackgroundImage.cpp \ + jni/src/gui/guiBox.cpp \ jni/src/gui/guiButton.cpp \ + jni/src/gui/guiButtonImage.cpp \ + jni/src/gui/guiButtonItemImage.cpp \ jni/src/gui/guiChatConsole.cpp \ jni/src/gui/guiConfirmRegistration.cpp \ jni/src/gui/guiEditBoxWithScrollbar.cpp \ jni/src/gui/guiEngine.cpp \ jni/src/gui/guiFormSpecMenu.cpp \ + jni/src/gui/guiHyperText.cpp \ + jni/src/gui/guiInventoryList.cpp \ + jni/src/gui/guiItemImage.cpp \ jni/src/gui/guiKeyChangeMenu.cpp \ jni/src/gui/guiPasswordChange.cpp \ jni/src/gui/guiPathSelectMenu.cpp \ diff -Nru minetest-5.1.1/build/android/Makefile minetest-5.2.0/build/android/Makefile --- minetest-5.1.1/build/android/Makefile 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/build/android/Makefile 2020-04-05 17:53:12.000000000 +0000 @@ -112,7 +112,7 @@ FREETYPE_TIMESTAMP_INT = $(ANDR_ROOT)/deps/freetype_timestamp FREETYPE_URL_GIT = https://github.com/cdave1/freetype2-android -ICONV_VERSION = 1.14 +ICONV_VERSION = 1.16 ICONV_DIR = $(ANDR_ROOT)/deps/libiconv/ ICONV_LIB = $(ICONV_DIR)/lib/.libs/libiconv.so ICONV_TIMESTAMP = $(ICONV_DIR)timestamp @@ -445,9 +445,6 @@ tar -xzf libiconv-${ICONV_VERSION}.tar.gz || exit 1; \ rm libiconv-${ICONV_VERSION}.tar.gz; \ ln -s libiconv-${ICONV_VERSION} libiconv; \ - cd ${ICONV_DIR}; \ - patch -p1 < ${ANDR_ROOT}/patches/libiconv_android.patch; \ - patch -p1 < ${ANDR_ROOT}/patches/libiconv_stdio.patch; \ fi iconv : $(ICONV_LIB) diff -Nru minetest-5.1.1/build/android/patches/libiconv_android.patch minetest-5.2.0/build/android/patches/libiconv_android.patch --- minetest-5.1.1/build/android/patches/libiconv_android.patch 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/build/android/patches/libiconv_android.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ ---- a/libcharset/lib/localcharset.c 2015-06-10 11:55:25.933870724 +0200 -+++ b/libcharset/lib/localcharset.c 2015-06-10 11:55:39.578063493 +0200 -@@ -47,7 +47,7 @@ - - #if !defined WIN32_NATIVE - # include --# if HAVE_LANGINFO_CODESET -+# if HAVE_LANGINFO_CODESET && !(defined __ANDROID__) - # include - # else - # if 0 /* see comment below */ -@@ -124,7 +124,7 @@ get_charset_aliases (void) - cp = charset_aliases; - if (cp == NULL) - { --#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) -+#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__ || defined __ANDROID__) - const char *dir; - const char *base = "charset.alias"; - char *file_name; -@@ -338,6 +338,9 @@ get_charset_aliases (void) - "CP54936" "\0" "GB18030" "\0" - "CP65001" "\0" "UTF-8" "\0"; - # endif -+# if defined __ANDROID__ -+ cp = "*" "\0" "UTF-8" "\0"; -+# endif - #endif - - charset_aliases = cp; -@@ -361,7 +364,7 @@ locale_charset (void) - const char *codeset; - const char *aliases; - --#if !(defined WIN32_NATIVE || defined OS2) -+#if !(defined WIN32_NATIVE || defined OS2 || defined __ANDROID__) - - # if HAVE_LANGINFO_CODESET - diff -Nru minetest-5.1.1/build/android/patches/libiconv_stdio.patch minetest-5.2.0/build/android/patches/libiconv_stdio.patch --- minetest-5.1.1/build/android/patches/libiconv_stdio.patch 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/build/android/patches/libiconv_stdio.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ ---- a/srclib/stdio.in.h 2011-08-07 15:42:06.000000000 +0200 -+++ b/srclib/stdio.in.h 2015-06-10 09:27:58.129056262 +0200 -@@ -695,8 +696,9 @@ _GL_CXXALIASWARN (gets); - /* It is very rare that the developer ever has full control of stdin, - so any use of gets warrants an unconditional warning. Assume it is - always declared, since it is required by C89. */ --_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); -+/*_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");*/ -+#define gets(a) fgets( a, sizeof(*(a)), stdin) - #endif - - -#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ diff -Nru minetest-5.1.1/builtin/common/information_formspecs.lua minetest-5.2.0/builtin/common/information_formspecs.lua --- minetest-5.1.1/builtin/common/information_formspecs.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/common/information_formspecs.lua 2020-04-05 17:53:12.000000000 +0000 @@ -136,14 +136,14 @@ core.show_formspec(name, "__builtin:help_privs", build_privs_formspec(name)) if name ~= admin then - return + 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 + return true end end diff -Nru minetest-5.1.1/builtin/common/misc_helpers.lua minetest-5.2.0/builtin/common/misc_helpers.lua --- minetest-5.1.1/builtin/common/misc_helpers.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/common/misc_helpers.lua 2020-04-05 17:53:12.000000000 +0000 @@ -5,7 +5,7 @@ local string_sub, string_find = string.sub, string.find -------------------------------------------------------------------------------- -function basic_dump(o) +local function basic_dump(o) local tp = type(o) if tp == "number" then return tostring(o) @@ -200,28 +200,11 @@ return -1 end -assert(table.indexof({"foo", "bar"}, "foo") == 1) -assert(table.indexof({"foo", "bar"}, "baz") == -1) - --------------------------------------------------------------------------------- -if INIT ~= "client" then - function file_exists(filename) - local f = io.open(filename, "r") - if f == nil then - return false - else - f:close() - return true - end - end -end -------------------------------------------------------------------------------- function string:trim() return (self:gsub("^%s*(.-)%s*$", "%1")) end -assert(string.trim("\n \t\tfoo bar\t ") == "foo bar") - -------------------------------------------------------------------------------- function math.hypot(x, y) local t @@ -259,64 +242,6 @@ return v end --------------------------------------------------------------------------------- -function get_last_folder(text,count) - local parts = text:split(DIR_DELIM) - - if count == nil then - return parts[#parts] - end - - local retval = "" - for i=1,count,1 do - retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM - end - - return retval -end - --------------------------------------------------------------------------------- -function cleanup_path(temppath) - - local parts = temppath:split("-") - temppath = "" - for i=1,#parts,1 do - if temppath ~= "" then - temppath = temppath .. "_" - end - temppath = temppath .. parts[i] - end - - parts = temppath:split(".") - temppath = "" - for i=1,#parts,1 do - if temppath ~= "" then - temppath = temppath .. "_" - end - temppath = temppath .. parts[i] - end - - parts = temppath:split("'") - temppath = "" - for i=1,#parts,1 do - if temppath ~= "" then - temppath = temppath .. "" - end - temppath = temppath .. parts[i] - end - - parts = temppath:split(" ") - temppath = "" - for i=1,#parts,1 do - if temppath ~= "" then - temppath = temppath - end - temppath = temppath .. parts[i] - end - - return temppath -end - function core.formspec_escape(text) if text ~= nil then text = string.gsub(text,"\\","\\\\") @@ -428,10 +353,9 @@ core.rotate_node = function(itemstack, placer, pointed_thing) local name = placer and placer:get_player_name() or "" local invert_wall = placer and placer:get_player_control().sneak or false - core.rotate_and_place(itemstack, placer, pointed_thing, + return core.rotate_and_place(itemstack, placer, pointed_thing, is_creative(name), {invert_wall = invert_wall}, true) - return itemstack end end @@ -521,9 +445,6 @@ return nil end -assert(core.string_to_pos("10.0, 5, -2").x == 10) -assert(core.string_to_pos("( 10.0, 5, -2)").z == -2) -assert(core.string_to_pos("asd, 5, -2)") == nil) -------------------------------------------------------------------------------- function core.string_to_area(value) @@ -576,6 +497,29 @@ end +function table.key_value_swap(t) + local ti = {} + for k,v in pairs(t) do + ti[v] = k + end + return ti +end + + +function table.shuffle(t, from, to, random) + from = from or 1 + to = to or #t + random = random or math.random + local n = to - from + 1 + while n > 1 do + local r = from + n-1 + local l = from + random(0, n-1) + t[l], t[r] = t[r], t[l] + n = n-1 + end +end + + -------------------------------------------------------------------------------- -- mainmenu only functions -------------------------------------------------------------------------------- @@ -756,6 +700,3 @@ end return table.concat(list, delim) end - -assert(core.string_to_privs("a,b").b == true) -assert(core.privs_to_string({a=true,b=true}) == "a,b") diff -Nru minetest-5.1.1/builtin/common/serialize.lua minetest-5.2.0/builtin/common/serialize.lua --- minetest-5.1.1/builtin/common/serialize.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/common/serialize.lua 2020-04-05 17:53:12.000000000 +0000 @@ -177,13 +177,16 @@ -- Deserialization -local env = { - loadstring = loadstring, -} - -local safe_env = { - loadstring = function() end, -} +local function safe_loadstring(...) + local func, err = loadstring(...) + if func then + setfenv(func, {}) + return func + end + return nil, err +end + +local function dummy_func() end function core.deserialize(str, safe) if type(str) ~= "string" then @@ -195,7 +198,10 @@ end local f, err = loadstring(str) if not f then return nil, err end - setfenv(f, safe and safe_env or env) + + -- The environment is recreated every time so deseralized code cannot + -- pollute it with permanent references. + setfenv(f, {loadstring = safe and dummy_func or safe_loadstring}) local good, data = pcall(f) if good then @@ -204,17 +210,3 @@ return nil, data end end - - --- Unit tests -local test_in = {cat={sound="nyan", speed=400}, dog={sound="woof"}} -local test_out = core.deserialize(core.serialize(test_in)) - -assert(test_in.cat.sound == test_out.cat.sound) -assert(test_in.cat.speed == test_out.cat.speed) -assert(test_in.dog.sound == test_out.dog.sound) - -test_in = {escape_chars="\n\r\t\v\\\"\'", non_european="θשׁ٩∂"} -test_out = core.deserialize(core.serialize(test_in)) -assert(test_in.escape_chars == test_out.escape_chars) -assert(test_in.non_european == test_out.non_european) diff -Nru minetest-5.1.1/builtin/common/tests/misc_helpers_spec.lua minetest-5.2.0/builtin/common/tests/misc_helpers_spec.lua --- minetest-5.1.1/builtin/common/tests/misc_helpers_spec.lua 1970-01-01 00:00:00.000000000 +0000 +++ minetest-5.2.0/builtin/common/tests/misc_helpers_spec.lua 2020-04-05 17:53:12.000000000 +0000 @@ -0,0 +1,73 @@ +_G.core = {} +dofile("builtin/common/misc_helpers.lua") + +describe("string", function() + it("trim()", function() + assert.equal("foo bar", string.trim("\n \t\tfoo bar\t ")) + end) + + describe("split()", function() + it("removes empty", function() + assert.same({ "hello" }, string.split("hello")) + assert.same({ "hello", "world" }, string.split("hello,world")) + assert.same({ "hello", "world" }, string.split("hello,world,,,")) + assert.same({ "hello", "world" }, string.split(",,,hello,world")) + assert.same({ "hello", "world", "2" }, string.split("hello,,,world,2")) + assert.same({ "hello ", " world" }, string.split("hello :| world", ":|")) + end) + + it("keeps empty", function() + assert.same({ "hello" }, string.split("hello", ",", true)) + assert.same({ "hello", "world" }, string.split("hello,world", ",", true)) + assert.same({ "hello", "world", "" }, string.split("hello,world,", ",", true)) + assert.same({ "hello", "", "", "world", "2" }, string.split("hello,,,world,2", ",", true)) + assert.same({ "", "", "hello", "world", "2" }, string.split(",,hello,world,2", ",", true)) + assert.same({ "hello ", " world | :" }, string.split("hello :| world | :", ":|")) + end) + + it("max_splits", function() + assert.same({ "one" }, string.split("one", ",", true, 2)) + assert.same({ "one,two,three,four" }, string.split("one,two,three,four", ",", true, 0)) + assert.same({ "one", "two", "three,four" }, string.split("one,two,three,four", ",", true, 2)) + assert.same({ "one", "", "two,three,four" }, string.split("one,,two,three,four", ",", true, 2)) + assert.same({ "one", "two", "three,four" }, string.split("one,,,,,,two,three,four", ",", false, 2)) + end) + + it("pattern", function() + assert.same({ "one", "two" }, string.split("one,two", ",", false, -1, true)) + assert.same({ "one", "two", "three" }, string.split("one2two3three", "%d", false, -1, true)) + end) + end) +end) + +describe("privs", function() + it("from string", function() + assert.same({ a = true, b = true }, core.string_to_privs("a,b")) + end) + + it("to string", function() + assert.equal("one", core.privs_to_string({ one=true })) + + local ret = core.privs_to_string({ a=true, b=true }) + assert(ret == "a,b" or ret == "b,a") + end) +end) + +describe("pos", function() + it("from string", function() + assert.same({ x = 10, y = 5.1, z = -2}, core.string_to_pos("10.0, 5.1, -2")) + assert.same({ x = 10, y = 5.1, z = -2}, core.string_to_pos("( 10.0, 5.1, -2)")) + assert.is_nil(core.string_to_pos("asd, 5, -2)")) + end) + + it("to string", function() + assert.equal("(10.1,5.2,-2.3)", core.pos_to_string({ x = 10.1, y = 5.2, z = -2.3})) + end) +end) + +describe("table", function() + it("indexof()", function() + assert.equal(1, table.indexof({"foo", "bar"}, "foo")) + assert.equal(-1, table.indexof({"foo", "bar"}, "baz")) + end) +end) diff -Nru minetest-5.1.1/builtin/common/tests/serialize_spec.lua minetest-5.2.0/builtin/common/tests/serialize_spec.lua --- minetest-5.1.1/builtin/common/tests/serialize_spec.lua 1970-01-01 00:00:00.000000000 +0000 +++ minetest-5.2.0/builtin/common/tests/serialize_spec.lua 2020-04-05 17:53:12.000000000 +0000 @@ -0,0 +1,44 @@ +_G.core = {} + +_G.setfenv = require 'busted.compatibility'.setfenv + +dofile("builtin/common/serialize.lua") + +describe("serialize", function() + it("works", function() + local test_in = {cat={sound="nyan", speed=400}, dog={sound="woof"}} + local test_out = core.deserialize(core.serialize(test_in)) + + assert.same(test_in, test_out) + end) + + it("handles characters", function() + local test_in = {escape_chars="\n\r\t\v\\\"\'", non_european="θשׁ٩∂"} + local test_out = core.deserialize(core.serialize(test_in)) + assert.same(test_in, test_out) + end) + + it("handles recursive structures", function() + local test_in = { hello = "world" } + test_in.foo = test_in + + local test_out = core.deserialize(core.serialize(test_in)) + assert.same(test_in, test_out) + end) + + it("strips functions in safe mode", function() + local test_in = { + func = function(a, b) + error("test") + end, + foo = "bar" + } + + local str = core.serialize(test_in) + assert.not_nil(str:find("loadstring")) + + local test_out = core.deserialize(str, true) + assert.is_nil(test_out.func) + assert.equals(test_out.foo, "bar") + end) +end) diff -Nru minetest-5.1.1/builtin/common/tests/vector_spec.lua minetest-5.2.0/builtin/common/tests/vector_spec.lua --- minetest-5.1.1/builtin/common/tests/vector_spec.lua 1970-01-01 00:00:00.000000000 +0000 +++ minetest-5.2.0/builtin/common/tests/vector_spec.lua 2020-04-05 17:53:12.000000000 +0000 @@ -0,0 +1,46 @@ +_G.vector = {} +dofile("builtin/common/vector.lua") + +describe("vector", function() + describe("new()", function() + it("constructs", function() + assert.same({ x = 0, y = 0, z = 0 }, vector.new()) + assert.same({ x = 1, y = 2, z = 3 }, vector.new(1, 2, 3)) + assert.same({ x = 3, y = 2, z = 1 }, vector.new({ x = 3, y = 2, z = 1 })) + + local input = vector.new({ x = 3, y = 2, z = 1 }) + local output = vector.new(input) + assert.same(input, output) + assert.are_not.equal(input, output) + end) + + it("throws on invalid input", function() + assert.has.errors(function() + vector.new({ x = 3 }) + end) + + assert.has.errors(function() + vector.new({ d = 3 }) + end) + end) + end) + + it("equal()", function() + local function assertE(a, b) + assert.is_true(vector.equals(a, b)) + end + local function assertNE(a, b) + assert.is_false(vector.equals(a, b)) + end + + assertE({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) + assertE({x = -1, y = 0, z = 1}, {x = -1, y = 0, z = 1}) + local a = { x = 2, y = 4, z = -10 } + assertE(a, a) + assertNE({x = -1, y = 0, z = 1}, a) + end) + + it("add()", function() + assert.same({ x = 2, y = 4, z = 6 }, vector.add(vector.new(1, 2, 3), { x = 1, y = 2, z = 3 })) + end) +end) diff -Nru minetest-5.1.1/builtin/game/chat.lua minetest-5.2.0/builtin/game/chat.lua --- minetest-5.1.1/builtin/game/chat.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/chat.lua 2020-04-05 17:53:12.000000000 +0000 @@ -115,6 +115,7 @@ privs = {shout=true}, func = function(name, param) core.chat_send_all("* " .. name .. " " .. param) + return true end, }) @@ -141,7 +142,7 @@ end return true, "Privileges of " .. name .. ": " .. core.privs_to_string( - core.get_player_privs(name), ' ') + core.get_player_privs(name), ", ") end, }) @@ -919,12 +920,13 @@ core.chat_send_all("*** Server shutting down (operator request).") end core.request_shutdown(message:trim(), core.is_yes(reconnect), delay) + return true end, }) core.register_chatcommand("ban", { - params = "[ | ]", - description = "Ban player or show ban list", + params = "[]", + description = "Ban the IP of a player or show the ban list", privs = {ban=true}, func = function(name, param) if param == "" then @@ -936,7 +938,7 @@ end end if not core.get_player_by_name(param) then - return false, "No such player." + return false, "Player is not online." end if not core.ban_player(param) then return false, "Failed to ban player." @@ -949,7 +951,7 @@ core.register_chatcommand("unban", { params = " | ", - description = "Remove player ban", + description = "Remove IP ban belonging to a player/IP", privs = {ban=true}, func = function(name, param) if not core.unban_player_or_ip(param) then @@ -995,12 +997,13 @@ core.log("action", name .. " clears all objects (" .. options.mode .. " mode).") - core.chat_send_all("Clearing all objects. This may take long." - .. " You may experience a timeout. (by " + core.chat_send_all("Clearing all objects. This may take a long time." + .. " You may experience a timeout. (by " .. name .. ")") core.clear_objects(options) core.log("action", "Object clearing done.") core.chat_send_all("*** Cleared all objects.") + return true end, }) diff -Nru minetest-5.1.1/builtin/game/deprecated.lua minetest-5.2.0/builtin/game/deprecated.lua --- minetest-5.1.1/builtin/game/deprecated.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/deprecated.lua 2020-04-05 17:53:12.000000000 +0000 @@ -20,7 +20,7 @@ end function core.add_to_creative_inventory(itemstring) - core.log("deprecated", "core.add_to_creative_inventory: This function is deprecated and does nothing.") + core.log("deprecated", "core.add_to_creative_inventory is obsolete and does nothing.") end -- diff -Nru minetest-5.1.1/builtin/game/falling.lua minetest-5.2.0/builtin/game/falling.lua --- minetest-5.1.1/builtin/game/falling.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/falling.lua 2020-04-05 17:53:12.000000000 +0000 @@ -1,6 +1,34 @@ -- Minetest: builtin/item.lua local builtin_shared = ... +local SCALE = 0.667 + +local facedir_to_euler = { + {y = 0, x = 0, z = 0}, + {y = -math.pi/2, x = 0, z = 0}, + {y = math.pi, x = 0, z = 0}, + {y = math.pi/2, x = 0, z = 0}, + {y = math.pi/2, x = -math.pi/2, z = math.pi/2}, + {y = math.pi/2, x = math.pi, z = math.pi/2}, + {y = math.pi/2, x = math.pi/2, z = math.pi/2}, + {y = math.pi/2, x = 0, z = math.pi/2}, + {y = -math.pi/2, x = math.pi/2, z = math.pi/2}, + {y = -math.pi/2, x = 0, z = math.pi/2}, + {y = -math.pi/2, x = -math.pi/2, z = math.pi/2}, + {y = -math.pi/2, x = math.pi, z = math.pi/2}, + {y = 0, x = 0, z = math.pi/2}, + {y = 0, x = -math.pi/2, z = math.pi/2}, + {y = 0, x = math.pi, z = math.pi/2}, + {y = 0, x = math.pi/2, z = math.pi/2}, + {y = math.pi, x = math.pi, z = math.pi/2}, + {y = math.pi, x = math.pi/2, z = math.pi/2}, + {y = math.pi, x = 0, z = math.pi/2}, + {y = math.pi, x = -math.pi/2, z = math.pi/2}, + {y = math.pi, x = math.pi, z = 0}, + {y = -math.pi/2, x = math.pi, z = 0}, + {y = 0, x = math.pi, z = 0}, + {y = math.pi/2, x = math.pi, z = 0} +} -- -- Falling stuff @@ -8,8 +36,8 @@ core.register_entity(":__builtin:falling_node", { initial_properties = { - visual = "wielditem", - visual_size = {x = 0.667, y = 0.667}, + visual = "item", + visual_size = {x = SCALE, y = SCALE, z = SCALE}, textures = {}, physical = true, is_visible = false, @@ -33,11 +61,105 @@ end end end + local def = core.registered_nodes[node.name] + if not def then + -- Don't allow unknown nodes to fall + core.log("info", + "Unknown falling node removed at ".. + core.pos_to_string(self.object:get_pos())) + self.object:remove() + return + end self.meta = meta - self.object:set_properties({ - is_visible = true, - textures = {node.name}, - }) + if def.drawtype == "torchlike" or def.drawtype == "signlike" then + local textures + if def.tiles and def.tiles[1] then + local tile = def.tiles[1] + if type(tile) == "table" then + tile = tile.name + end + if def.drawtype == "torchlike" then + textures = { "("..tile..")^[transformFX", tile } + else + textures = { tile, "("..tile..")^[transformFX" } + end + end + local vsize + if def.visual_scale then + local s = def.visual_scale + vsize = {x = s, y = s, z = s} + end + self.object:set_properties({ + is_visible = true, + visual = "upright_sprite", + visual_size = vsize, + textures = textures, + glow = def.light_source, + }) + elseif def.drawtype ~= "airlike" then + local itemstring = node.name + if core.is_colored_paramtype(def.paramtype2) then + itemstring = core.itemstring_with_palette(itemstring, node.param2) + end + local vsize + if def.visual_scale then + local s = def.visual_scale * SCALE + vsize = {x = s, y = s, z = s} + end + self.object:set_properties({ + is_visible = true, + wield_item = itemstring, + visual_size = vsize, + glow = def.light_source, + }) + end + -- Rotate entity + if def.drawtype == "torchlike" then + self.object:set_yaw(math.pi*0.25) + elseif (node.param2 ~= 0 and (def.wield_image == "" + or def.wield_image == nil)) + or def.drawtype == "signlike" + or def.drawtype == "mesh" + or def.drawtype == "normal" + or def.drawtype == "nodebox" then + if (def.paramtype2 == "facedir" or def.paramtype2 == "colorfacedir") then + local fdir = node.param2 % 32 + -- Get rotation from a precalculated lookup table + local euler = facedir_to_euler[fdir + 1] + if euler then + self.object:set_rotation(euler) + end + elseif (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted") then + local rot = node.param2 % 8 + local pitch, yaw, roll = 0, 0, 0 + if rot == 1 then + pitch, yaw = math.pi, math.pi + elseif rot == 2 then + pitch, yaw = math.pi/2, math.pi/2 + elseif rot == 3 then + pitch, yaw = math.pi/2, -math.pi/2 + elseif rot == 4 then + pitch, yaw = math.pi/2, math.pi + elseif rot == 5 then + pitch, yaw = math.pi/2, 0 + end + if def.drawtype == "signlike" then + pitch = pitch - math.pi/2 + if rot == 0 then + yaw = yaw + math.pi/2 + elseif rot == 1 then + yaw = yaw - math.pi/2 + end + elseif def.drawtype == "mesh" or def.drawtype == "normal" then + if rot >= 0 and rot <= 1 then + roll = roll + math.pi + else + yaw = yaw + math.pi + end + end + self.object:set_rotation({x=pitch, y=yaw, z=roll}) + end + end end, get_staticdata = function(self) @@ -128,7 +250,7 @@ meta:from_table(self.meta) end if def.sounds and def.sounds.place then - core.sound_play(def.sounds.place, {pos = np}) + core.sound_play(def.sounds.place, {pos = np}, true) end end self.object:remove() @@ -154,7 +276,7 @@ local def = core.registered_nodes[node.name] if def and def.sounds and def.sounds.fall then - core.sound_play(def.sounds.fall, {pos = pos}) + core.sound_play(def.sounds.fall, {pos = pos}, true) end obj:get_luaentity():set_node(node, metatable) @@ -187,7 +309,7 @@ def.preserve_metadata(pos_copy, node_copy, oldmeta, drops) end if def and def.sounds and def.sounds.fall then - core.sound_play(def.sounds.fall, {pos = p}) + core.sound_play(def.sounds.fall, {pos = p}, true) end core.remove_node(p) for _, item in pairs(drops) do diff -Nru minetest-5.1.1/builtin/game/features.lua minetest-5.2.0/builtin/game/features.lua --- minetest-5.1.1/builtin/game/features.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/features.lua 2020-04-05 17:53:12.000000000 +0000 @@ -15,6 +15,7 @@ httpfetch_binary_data = true, formspec_version_element = true, area_store_persistent_ids = true, + pathfinder_works = true, } function core.has_feature(arg) diff -Nru minetest-5.1.1/builtin/game/item_entity.lua minetest-5.2.0/builtin/game/item_entity.lua --- minetest-5.1.1/builtin/game/item_entity.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/item_entity.lua 2020-04-05 17:53:12.000000000 +0000 @@ -58,6 +58,8 @@ local count = math.min(stack:get_count(), max_count) local size = 0.2 + 0.1 * (count / max_count) ^ (1 / 3) local coll_height = size * 0.75 + local def = core.registered_nodes[itemname] + local glow = def and math.floor(def.light_source / 2 + 0.5) self.object:set_properties({ is_visible = true, @@ -69,6 +71,7 @@ selectionbox = {-size, -size, -size, size, size, size}, automatic_rotate = math.pi * 0.5 * 0.2 / size, wield_item = self.itemstring, + glow = glow, }) end, diff -Nru minetest-5.1.1/builtin/game/item.lua minetest-5.2.0/builtin/game/item.lua --- minetest-5.1.1/builtin/game/item.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/item.lua 2020-04-05 17:53:12.000000000 +0000 @@ -259,7 +259,7 @@ prevent_after_place) local def = itemstack:get_definition() if def.type ~= "node" or pointed_thing.type ~= "node" then - return itemstack, false + return itemstack, nil end local under = pointed_thing.under @@ -272,7 +272,7 @@ if not oldnode_under or not oldnode_above then log("info", playername .. " tried to place" .. " node in unloaded position " .. core.pos_to_string(above)) - return itemstack, false + return itemstack, nil end local olddef_under = core.registered_nodes[oldnode_under.name] @@ -284,7 +284,7 @@ log("info", playername .. " tried to place" .. " node in invalid position " .. core.pos_to_string(above) .. ", replacing " .. oldnode_above.name) - return itemstack, false + return itemstack, nil end -- Place above pointed node @@ -302,12 +302,9 @@ .. " at protected position " .. core.pos_to_string(place_to)) core.record_protection_violation(place_to, playername) - return itemstack + return itemstack, nil end - log("action", playername .. " places node " - .. def.name .. " at " .. core.pos_to_string(place_to)) - local oldnode = core.get_node(place_to) local newnode = {name = def.name, param1 = 0, param2 = param2 or 0} @@ -333,7 +330,7 @@ z = above.z - placer_pos.z } newnode.param2 = core.dir_to_facedir(dir) - log("action", "facedir: " .. newnode.param2) + log("info", "facedir: " .. newnode.param2) end end @@ -361,12 +358,23 @@ not builtin_shared.check_attached_node(place_to, newnode) then log("action", "attached node " .. def.name .. " can not be placed at " .. core.pos_to_string(place_to)) - return itemstack, false + return itemstack, nil end + log("action", playername .. " places node " + .. def.name .. " at " .. core.pos_to_string(place_to)) + -- Add node and update core.add_node(place_to, newnode) + -- Play sound if it was done by a player + if playername ~= "" and def.sounds and def.sounds.place then + core.sound_play(def.sounds.place, { + pos = place_to, + exclude_player = playername, + }, true) + end + local take_item = true -- Run callback @@ -395,9 +403,10 @@ if take_item then itemstack:take_item() end - return itemstack, true + return itemstack, place_to end +-- deprecated, item_place does not call this function core.item_place_object(itemstack, placer, pointed_thing) local pos = core.get_pointed_thing_position(pointed_thing, true) if pos ~= nil then @@ -415,14 +424,15 @@ local nn = n.name if core.registered_nodes[nn] and core.registered_nodes[nn].on_rightclick then return core.registered_nodes[nn].on_rightclick(pointed_thing.under, n, - placer, itemstack, pointed_thing) or itemstack, false + placer, itemstack, pointed_thing) or itemstack, nil end end + -- Place if node, otherwise do nothing if itemstack:get_definition().type == "node" then return core.item_place_node(itemstack, placer, pointed_thing, param2) end - return itemstack + return itemstack, nil end function core.item_secondary_use(itemstack, placer) @@ -465,7 +475,10 @@ user:set_hp(user:get_hp() + hp_change) if def and def.sound and def.sound.eat then - minetest.sound_play(def.sound.eat, { pos = user:get_pos(), max_hear_distance = 16 }) + core.sound_play(def.sound.eat, { + pos = user:get_pos(), + max_hear_distance = 16 + }, true) end if replace_with_item then @@ -572,7 +585,10 @@ if not core.settings:get_bool("creative_mode") then wielded:add_wear(dp.wear) if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then - core.sound_play(wdef.sound.breaks, {pos = pos, gain = 0.5}) + core.sound_play(wdef.sound.breaks, { + pos = pos, + gain = 0.5 + }, true) end end end @@ -604,6 +620,14 @@ -- Remove node and update core.remove_node(pos) + -- Play sound if it was done by a player + if diggername ~= "" and def and def.sounds and def.sounds.dug then + core.sound_play(def.sounds.dug, { + pos = pos, + exclude_player = diggername, + }, true) + end + -- Run callback if def and def.after_dig_node then -- Copy pos and node because callback can modify them diff -Nru minetest-5.1.1/builtin/game/misc.lua minetest-5.2.0/builtin/game/misc.lua --- minetest-5.1.1/builtin/game/misc.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/misc.lua 2020-04-05 17:53:12.000000000 +0000 @@ -40,9 +40,6 @@ end -local player_list = {} - - function core.send_join_message(player_name) if not core.is_singleplayer() then core.chat_send_all("*** " .. player_name .. " joined the game.") @@ -61,7 +58,6 @@ core.register_on_joinplayer(function(player) local player_name = player:get_player_name() - player_list[player_name] = player if not core.is_singleplayer() then local status = core.get_server_status(player_name, true) if status and status ~= "" then @@ -74,22 +70,10 @@ core.register_on_leaveplayer(function(player, timed_out) local player_name = player:get_player_name() - player_list[player_name] = nil core.send_leave_message(player_name, timed_out) end) -function core.get_connected_players() - local temp_table = {} - for index, value in pairs(player_list) do - if value:is_player_connected() then - temp_table[#temp_table + 1] = value - end - end - return temp_table -end - - function core.is_player(player) -- a table being a player is also supported because it quacks sufficiently -- like a player if it has the is_player function diff -Nru minetest-5.1.1/builtin/game/register.lua minetest-5.2.0/builtin/game/register.lua --- minetest-5.1.1/builtin/game/register.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/game/register.lua 2020-04-05 17:53:12.000000000 +0000 @@ -321,11 +321,11 @@ end --- Deprecated: +-- Obsolete: -- Aliases for core.register_alias (how ironic...) ---core.alias_node = core.register_alias ---core.alias_tool = core.register_alias ---core.alias_craftitem = core.register_alias +-- core.alias_node = core.register_alias +-- core.alias_tool = core.register_alias +-- core.alias_craftitem = core.register_alias -- -- Built-in node definitions. Also defined in C. diff -Nru minetest-5.1.1/builtin/mainmenu/dlg_settings_advanced.lua minetest-5.2.0/builtin/mainmenu/dlg_settings_advanced.lua --- minetest-5.1.1/builtin/mainmenu/dlg_settings_advanced.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/mainmenu/dlg_settings_advanced.lua 2020-04-05 17:53:12.000000000 +0000 @@ -639,12 +639,23 @@ -- Flags formspec = table.concat(fields) .. "checkbox[0.5," .. height - 0.6 .. ";cb_defaults;" + --[[~ "defaults" is a noise parameter flag. + It describes the default processing options + for noise settings in main menu -> "All Settings". ]] .. fgettext("defaults") .. ";" -- defaults .. tostring(flags["defaults"] == true) .. "]" -- to get false if nil .. "checkbox[5," .. height - 0.6 .. ";cb_eased;" + --[[~ "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". ]] .. fgettext("eased") .. ";" -- eased .. tostring(flags["eased"] == true) .. "]" .. "checkbox[5," .. height - 0.15 .. ";cb_absvalue;" + --[[~ "absvalue" is a noise parameter flag. + It is short for "absolute value". + It can be enabled in noise settings in + main menu -> "All Settings". ]] .. fgettext("absvalue") .. ";" -- absvalue .. tostring(flags["absvalue"] == true) .. "]" height = height + 1 diff -Nru minetest-5.1.1/builtin/mainmenu/pkgmgr.lua minetest-5.2.0/builtin/mainmenu/pkgmgr.lua --- minetest-5.1.1/builtin/mainmenu/pkgmgr.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/mainmenu/pkgmgr.lua 2020-04-05 17:53:12.000000000 +0000 @@ -16,6 +16,62 @@ --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -------------------------------------------------------------------------------- +local function get_last_folder(text,count) + local parts = text:split(DIR_DELIM) + + if count == nil then + return parts[#parts] + end + + local retval = "" + for i=1,count,1 do + retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM + end + + return retval +end + +local function cleanup_path(temppath) + + local parts = temppath:split("-") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath .. "_" + end + temppath = temppath .. parts[i] + end + + parts = temppath:split(".") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath .. "_" + end + temppath = temppath .. parts[i] + end + + parts = temppath:split("'") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath .. "" + end + temppath = temppath .. parts[i] + end + + parts = temppath:split(" ") + temppath = "" + for i=1,#parts,1 do + if temppath ~= "" then + temppath = temppath + end + temppath = temppath .. parts[i] + end + + return temppath +end + function get_mods(path,retval,modpack) local mods = core.get_dir_list(path, true) @@ -403,9 +459,9 @@ -- Make a list of mod ids indexed by their names local mod_ids = {} - for id, mod in pairs(list) do - if mod.type == "mod" and not mod.is_modpack then - mod_ids[mod.name] = id + for id, mod2 in pairs(list) do + if mod2.type == "mod" and not mod2.is_modpack then + mod_ids[mod2.name] = id end end @@ -429,17 +485,17 @@ if not enabled_mods[name] then enabled_mods[name] = true - local mod = list[mod_ids[name]] - if not mod then + local mod_to_enable = list[mod_ids[name]] + if not mod_to_enable then minetest.log("warning", "Mod dependency \"" .. name .. "\" not found!") else - if mod.enabled == false then - mod.enabled = true - toggled_mods[#toggled_mods+1] = mod.name + if mod_to_enable.enabled == false 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.path) + local depends = pkgmgr.get_dependencies(mod_to_enable.path) for i = 1, #depends do if not enabled_mods[name] then sp = sp+1 diff -Nru minetest-5.1.1/builtin/mainmenu/tab_credits.lua minetest-5.2.0/builtin/mainmenu/tab_credits.lua --- minetest-5.1.1/builtin/mainmenu/tab_credits.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/mainmenu/tab_credits.lua 2020-04-05 17:53:12.000000000 +0000 @@ -20,51 +20,31 @@ local core_developers = { "Perttu Ahola (celeron55) ", "sfan5 ", - "ShadowNinja ", "Nathanaël Courant (Nore/Ekdohibs) ", "Loic Blot (nerzhul/nrz) ", "paramat", "Auke Kok (sofar) ", - "rubenwardy ", + "Andrew Ward (rubenwardy) ", "Krock/SmallJoker ", "Lars Hofhansl ", } local active_contributors = { - "numberZero [Audiovisuals: meshgen]", - "stujones11 [Android UX improvements]", - "red-001 [CSM & Menu fixes]", - "Paul Ouellette (pauloue) [Docs, fixes]", - "Dániel Juhász (juhdanad) [Audiovisuals: lighting]", - "Hybrid Dog [API]", - "srifqi [Android]", - "Vincent Glize (Dumbeldor) [Cleanups, CSM APIs]", - "Ben Deutsch [Rendering, Fixes, SQLite auth]", - "Wuzzy [Translation, Slippery]", - "ANAND (ClobberXD) [Docs, Fixes]", - "Shara/Ezhh [Docs, Game API]", - "DTA7 [Fixes, mute key]", - "Thomas-S [Disconnected, Formspecs]", - "Raymoo [Tool Capabilities]", - "Elijah Duffy (octacian) [Mainmenu]", - "noob3167 [Fixes]", - "adelcoding1 [Formspecs]", - "adrido [Windows Installer, Formspecs]", - "Rui [Sound Pitch]", - "Jean-Patrick G (kilbith) [Audiovisuals]", - "Esteban (EXio4) [Cleanups]", - "Vaughan Lapsley (vlapsley) [Carpathian mapgen]", - "CoderForTheBetter [Add set_rotation]", - "Quentin Bazin (Unarelith) [Cleanups]", + "Hugues Ross [Formspecs]", "Maksim (MoNTE48) [Android]", - "Gaël-de-Sailly [Mapgen, pitch fly]", - "zeuner [Docs, Fixes]", - "ThomasMonroe314 (tre) [Fixes]", - "Rob Blanckaert (basicer) [Fixes]", - "Jozef Behran (osjc) [Fixes]", - "random-geek [Fixes]", - "Pedro Gimeno (pgimeno) [Fixes]", - "lisacvuk [Fixes]", + "DS [Formspecs]", + "pyrollo [Formspecs: Hypertext]", + "v-rob [Formspecs]", + "Jordach [set_sky]", + "random-geek [Formspecs]", + "Wuzzy [Pathfinder, builtin, translations]", + "ANAND (ClobberXD) [Fixes, per-player FOV]", + "Warr1024 [Fixes]", + "Paul Ouellette (pauloue) [Fixes, Script API]", + "Jean-Patrick G (kilbith) [Audiovisuals]", + "HybridDog [Script API]", + "dcbrwn [Object shading]", + "srifqi [Fixes]", } local previous_core_developers = { @@ -79,24 +59,31 @@ "Ryan Kwolek (kwolekr) ", "sapier", "Zeno", + "ShadowNinja ", } local previous_contributors = { - "Gregory Currie (gregorycu) [optimisation]", - "Diego Martínez (kaeza) ", - "T4im [Profiler]", - "TeTpaAka [Hand overriding, nametag colors]", - "Duane Robertson [MGValleys]", - "neoascetic [OS X Fixes]", - "TriBlade9 [Audiovisuals]", - "Jurgen Doser (doserj) [Fixes]", - "MirceaKitsune [Audiovisuals]", - "Guiseppe Bilotta (Oblomov) [Fixes]", - "matttpt [Fixes]", "Nils Dagsson Moskopp (erlehmann) [Minetest Logo]", + "Dániel Juhász (juhdanad) ", + "red-001 ", + "numberZero [Audiovisuals: meshgen]", + "Giuseppe Bilotta", + "MirceaKitsune ", + "Constantin Wenger (SpeedProg)", + "Ciaran Gultnieks (CiaranG)", + "stujones11 [Android UX improvements]", "Jeija [HTTP, particles]", - "bigfoot547 [CSM]", + "Vincent Glize (Dumbeldor) [Cleanups, CSM APIs]", + "Ben Deutsch [Rendering, Fixes, SQLite auth]", + "TeTpaAka [Hand overriding, nametag colors]", + "Rui [Sound Pitch]", + "Duane Robertson [MGValleys]", + "Raymoo [Tool Capabilities]", "Rogier [Fixes]", + "Gregory Currie (gregorycu) [optimisation]", + "TriBlade9 [Audiovisuals]", + "T4im [Profiler]", + "Jurgen Doser (doserj) ", } local function buildCreditList(source) diff -Nru minetest-5.1.1/builtin/mainmenu/tab_online.lua minetest-5.2.0/builtin/mainmenu/tab_online.lua --- minetest-5.1.1/builtin/mainmenu/tab_online.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/mainmenu/tab_online.lua 2020-04-05 17:53:12.000000000 +0000 @@ -78,6 +78,7 @@ "text,align=right,padding=0.25;" .. -- clients_max image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" .. image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" .. + --~ PvP = Player versus Player image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. "color,span=1;" .. "text,padding=1]" .. diff -Nru minetest-5.1.1/builtin/profiler/instrumentation.lua minetest-5.2.0/builtin/profiler/instrumentation.lua --- minetest-5.1.1/builtin/profiler/instrumentation.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/profiler/instrumentation.lua 2020-04-05 17:53:12.000000000 +0000 @@ -162,7 +162,7 @@ "on_activate", "on_step", "on_punch", - "rightclick", + "on_rightclick", "get_staticdata", } -- Wrap register_entity() to instrument them on registration. diff -Nru minetest-5.1.1/builtin/settingtypes.txt minetest-5.2.0/builtin/settingtypes.txt --- minetest-5.1.1/builtin/settingtypes.txt 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/builtin/settingtypes.txt 2020-04-05 17:53:12.000000000 +0000 @@ -440,7 +440,8 @@ [**Basic] -# Enable VBO +# Enable vertex buffer objects. +# This should greatly improve graphics performance. enable_vbo (VBO) bool true # Whether to fog out the end of the visible area. @@ -526,7 +527,10 @@ [***Tone Mapping] -# Enables filmic tone mapping +# Enables Hable's 'Uncharted 2' filmic tone mapping. +# Simulates the tone curve of photographic film and how this approximates the +# appearance of high dynamic range images. Mid-range contrast is slightly +# enhanced, highlights and shadows are gradually compressed. tone_mapping (Filmic tone mapping) bool false [***Bumpmapping] @@ -571,21 +575,31 @@ [***Waving Nodes] -# Set to true enables waving water. +# Set to true to enable waving liquids (like water). # Requires shaders to be enabled. -enable_waving_water (Waving water) bool false +enable_waving_water (Waving liquids) bool false -water_wave_height (Waving water wave height) float 1.0 +# The maximum height of the surface of waving liquids. +# 4.0 = Wave height is two nodes. +# 0.0 = Wave doesn't move at all. +# Default is 1.0 (1/2 node). +# Requires waving liquids to be enabled. +water_wave_height (Waving liquids wave height) float 1.0 0.0 4.0 + +# Length of liquid waves. +# Requires waving liquids to be enabled. +water_wave_length (Waving liquids wavelength) float 20.0 0.1 + +# How fast liquid waves will move. Higher = faster. +# If negative, liquid waves will move backwards. +# Requires waving liquids to be enabled. +water_wave_speed (Waving liquids wave speed) float 5.0 -water_wave_length (Waving water wavelength) float 20.0 - -water_wave_speed (Waving water wave speed) float 5.0 - -# Set to true enables waving leaves. +# Set to true to enable waving leaves. # Requires shaders to be enabled. enable_waving_leaves (Waving leaves) bool false -# Set to true enables waving plants. +# Set to true to enable waving plants. # Requires shaders to be enabled. enable_waving_plants (Waving plants) bool false @@ -609,11 +623,11 @@ # View distance in nodes. viewing_range (Viewing range) int 100 20 4000 -# Camera 'near clipping plane' distance in nodes, between 0 and 0.5. -# Most users will not need to change this. +# Camera 'near clipping plane' distance in nodes, between 0 and 0.25 +# Only works on GLES platforms. Most users will not need to change this. # Increasing can reduce artifacting on weaker GPUs. # 0.1 = Default, 0.25 = Good value for weaker tablets. -near_plane (Near clipping plane) float 0.1 0 0.5 +near_plane (Near plane) float 0.1 0 0.25 # Width component of the initial window size. screen_w (Screen width) int 1024 1 @@ -636,25 +650,34 @@ # Field of view in degrees. fov (Field of view) int 72 45 160 -# Adjust the gamma encoding for the light tables. Higher numbers are brighter. -# This setting is for the client only and is ignored by the server. -display_gamma (Gamma) float 1.0 0.5 10.0 +# Alters the light curve by applying 'gamma correction' to it. +# Higher values make middle and lower light levels brighter. +# Value '1.0' leaves the light curve unaltered. +# This only has significant effect on daylight and artificial +# light, it has very little effect on natural night light. +display_gamma (Light curve gamma) float 1.0 0.33 3.0 # Gradient of light curve at minimum light level. -lighting_alpha (Darkness sharpness) float 0.0 0.0 4.0 +# Controls the contrast of the lowest light levels. +lighting_alpha (Light curve low gradient) float 0.0 0.0 3.0 # Gradient of light curve at maximum light level. -lighting_beta (Lightness sharpness) float 1.5 0.0 4.0 - -# Strength of light curve mid-boost. -lighting_boost (Light curve mid boost) float 0.2 0.0 1.0 +# Controls the contrast of the highest light levels. +lighting_beta (Light curve high gradient) float 1.5 0.0 3.0 -# Center of light curve mid-boost. -lighting_boost_center (Light curve mid boost center) float 0.5 0.0 1.0 - -# Spread of light curve mid-boost. -# Standard deviation of the mid-boost gaussian. -lighting_boost_spread (Light curve mid boost spread) float 0.2 0.0 1.0 +# Strength of light curve boost. +# The 3 'boost' parameters define a range of the light +# curve that is boosted in brightness. +lighting_boost (Light curve boost) float 0.2 0.0 0.4 + +# Center of light curve boost range. +# Where 0.0 is minimum light level, 1.0 is maximum light level. +lighting_boost_center (Light curve boost center) float 0.5 0.0 1.0 + +# Spread of light curve boost range. +# Controls the width of the range to be boosted. +# Standard deviation of the light curve boost Gaussian. +lighting_boost_spread (Light curve boost spread) float 0.2 0.0 0.4 # Path to texture directory. All textures are first searched from here. texture_path (Texture path) path @@ -756,7 +779,7 @@ # True = 256 # False = 128 -# Useable to make minimap smoother on slower machines. +# Usable to make minimap smoother on slower machines. minimap_double_scan_height (Minimap scan height) bool true # Make fog and sky colors depend on daytime (dawn/sunset) and view direction. @@ -826,29 +849,60 @@ 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 -# Path to TrueTypeFont or bitmap. -font_path (Font path) filepath fonts/liberationsans.ttf +font_bold (Font bold by default) bool false -font_size (Font size) int 16 1 +font_italic (Font italic by default) bool false -# Font shadow offset, if 0 then shadow will not be drawn. +# Shadow offset (in pixels) of the default font. If 0, then shadow will not be drawn. font_shadow (Font shadow) int 1 -# Font shadow alpha (opaqueness, between 0 and 255). +# Opaqueness (alpha) of the shadow behind the default font, between 0 and 255. font_shadow_alpha (Font shadow alpha) int 127 0 255 -mono_font_path (Monospace font path) filepath fonts/liberationmono.ttf +# Font size of the default font in point (pt). +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. +# The fallback font will be used if the font cannot be loaded. +font_path (Regular font path) filepath fonts/Arimo-Regular.ttf + +font_path_bold (Bold font path) filepath fonts/Arimo-Bold.ttf +font_path_italic (Italic font path) filepath fonts/Arimo-Italic.ttf +font_path_bolditalic (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 -# This font will be used for certain languages. -fallback_font_path (Fallback font) filepath fonts/DroidSansFallbackFull.ttf +# 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. +# This font is used for e.g. the console and profiler screen. +mono_font_path (Monospace font path) filepath fonts/Cousine-Regular.ttf + +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_bolditalic (Bold and italic monospace font path) filepath fonts/Cousine-BoldItalic.ttf + +# Font size of the fallback font in point (pt). fallback_font_size (Fallback font size) int 15 1 + +# Shadow offset (in pixels) of the fallback font. If 0, then shadow will not be drawn. fallback_font_shadow (Fallback font shadow) int 1 + +# Opaqueness (alpha) of the shadow behind the fallback font, between 0 and 255. fallback_font_shadow_alpha (Fallback font shadow alpha) int 128 0 255 +# 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. +# 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 + # Path to save screenshots at. screenshot_path (Screenshot folder) path @@ -871,10 +925,20 @@ [Sound] +# Enables the sound system. +# If disabled, this completely disables all sounds everywhere and the in-game +# sound controls will be non-functional. +# Changing this setting requires a restart. enable_sound (Sound) bool true +# Volume of all sounds. +# Requires the sound system to be enabled. sound_volume (Volume) float 0.7 0.0 1.0 +# Whether to mute sounds. You can unmute sounds at any time, unless the +# sound system is disabled (enable_sound=false). +# In-game, you can toggle the mute state with the mute key or by using the +# pause menu. mute_sound (Mute sound) bool false [Client] @@ -975,6 +1039,7 @@ # Enable/disable running an IPv6 server. # Ignored if bind_address is set. +# Needs enable_ipv6 to be enabled. ipv6_server (IPv6 server) bool false [**Advanced] @@ -1145,10 +1210,10 @@ # Initial vertical speed when jumping, in nodes per second. movement_speed_jump (Jumping speed) float 6.5 -# Decrease this to increase liquid resistence to movement. +# Decrease this to increase liquid resistance to movement. movement_liquid_fluidity (Liquid fluidity) float 1 -# Maximum liquid resistence. Controls deceleration when entering liquid at +# Maximum liquid resistance. Controls deceleration when entering liquid at # high speed. movement_liquid_fluidity_smooth (Liquid fluidity smoothing) float 0.5 @@ -1160,7 +1225,7 @@ [**Advanced] -# Handling for deprecated lua api calls: +# Handling for deprecated Lua API calls: # - legacy: (try to) mimic old behaviour (default for release). # - log: mimic and log backtrace of deprecated call (default for debug). # - error: abort on usage of deprecated call (suggested for mod developers). @@ -1307,8 +1372,7 @@ # Set the language. Leave empty to use the system language. # A restart is required after changing this. -language (Language) enum ,be,ca,cs,da,de,dv,en,eo,es,et,fr,he,hu,id,it,ja,jbo,ko,ky,lt,ms,nb,nl,pl,pt,pt_BR,ro,ru,sl,sr_Cyrl,sv,sw,tr,uk,zh_CN,zh_TW - +language (Language) enum ,ar,ca,cs,da,de,dv,el,eo,es,et,eu,fil,fr,hu,id,it,ja,ja_KS,jbo,kk,kn,lo,lt,ms,my,nb,nl,nn,pl,pt,pt_BR,ro,ru,sl,sr_Cyrl,sv,sw,th,tr,uk,vi # Level of logging to be written to debug.txt: # - (no logging) @@ -1326,7 +1390,8 @@ # debug.txt is only moved if this setting is positive. debug_log_size_max (Debug log file size threshold) int 50 -# IPv6 support. +# Enable IPv6 support (for both client and server). +# Required for IPv6 connections to work at all. enable_ipv6 (IPv6) bool true [*Advanced] @@ -1405,14 +1470,27 @@ mgv5_spflags (Mapgen V5 specific flags) flags caverns caverns,nocaverns # Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. mgv5_cave_width (Cave width) float 0.09 # Y of upper limit of large caves. mgv5_large_cave_depth (Large cave depth) int -256 -# Deprecated, define and locate cave liquids using biome definitions instead. -# Y of upper limit of lava in large caves. -mgv5_lava_depth (Lava depth) int -256 +# Minimum limit of random number of small caves per mapchunk. +mgv5_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgv5_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgv5_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgv5_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgv5_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 # Y-level of cavern upper limit. mgv5_cavern_limit (Cavern limit) int -256 @@ -1522,30 +1600,27 @@ mgv7_mount_zero_level (Mountain zero level) int 0 # Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. mgv7_cave_width (Cave width) float 0.09 # Y of upper limit of large caves. mgv7_large_cave_depth (Large cave depth) int -33 -# Deprecated, define and locate cave liquids using biome definitions instead. -# Y of upper limit of lava in large caves. -mgv7_lava_depth (Lava depth) int -256 +# Minimum limit of random number of small caves per mapchunk. +mgv7_small_cave_num_min (Small cave minimum number) int 0 0 256 -# Controls the density of mountain-type floatlands. -# Is a noise offset added to the 'mgv7_np_mountain' noise value. -mgv7_float_mount_density (Floatland mountain density) float 0.6 +# Maximum limit of random number of small caves per mapchunk. +mgv7_small_cave_num_max (Small cave maximum number) int 0 0 256 -# Typical maximum height, above and below midpoint, of floatland mountains. -mgv7_float_mount_height (Floatland mountain height) float 128.0 +# Minimum limit of random number of large caves per mapchunk. +mgv7_large_cave_num_min (Large cave minimum number) int 0 0 64 -# Alters how mountain-type floatlands taper above and below midpoint. -mgv7_float_mount_exponent (Floatland mountain exponent) float 0.75 +# Maximum limit of random number of large caves per mapchunk. +mgv7_large_cave_num_max (Large cave maximum number) int 2 0 64 -# Y-level of floatland midpoint and lake surface. -mgv7_floatland_level (Floatland level) int 1280 - -# Y-level to which floatland shadows extend. -mgv7_shadow_limit (Shadow limit) int 1024 +# Proportion of large caves that contain liquid. +mgv7_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 # Y-level of cavern upper limit. mgv7_cavern_limit (Cavern limit) int -256 @@ -1586,13 +1661,6 @@ # Defines large-scale river channel structure. mgv7_np_ridge_uwater (Ridge underwater noise) noise_params_2d 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0, eased -# Defines areas of floatland smooth terrain. -# Smooth floatlands occur when noise > 0. -mgv7_np_floatland_base (Floatland base noise) noise_params_2d -0.6, 1.5, (600, 600, 600), 114, 5, 0.6, 2.0, eased - -# Variation of hill height and lake depth on floatland smooth terrain. -mgv7_np_float_base_height (Floatland base height noise) noise_params_2d 48, 24, (300, 300, 300), 907, 4, 0.7, 2.0, eased - # 3D noise defining mountain structure and height. # Also defines structure of floatland mountain terrain. mgv7_np_mountain (Mountain noise) noise_params_3d -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0 @@ -1630,14 +1698,27 @@ mgcarpathian_valley_width (River valley width) float 0.25 # Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. mgcarpathian_cave_width (Cave width) float 0.09 # Y of upper limit of large caves. mgcarpathian_large_cave_depth (Large cave depth) int -33 -# Deprecated, define and locate cave liquids using biome definitions instead. -# Y of upper limit of lava in large caves. -mgcarpathian_lava_depth (Lava depth) int -256 +# Minimum limit of random number of small caves per mapchunk. +mgcarpathian_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgcarpathian_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgcarpathian_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgcarpathian_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgcarpathian_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 # Y-level of cavern upper limit. mgcarpathian_cavern_limit (Cavern limit) int -256 @@ -1709,7 +1790,7 @@ [*Mapgen Flat] -# Map generation attributes specific to Mapgen flat. +# Map generation attributes specific to Mapgen Flat. # Occasional lakes and hills can be added to the flat world. mgflat_spflags (Mapgen Flat specific flags) flags nolakes,nohills lakes,hills,nolakes,nohills @@ -1719,11 +1800,24 @@ # Y of upper limit of large caves. mgflat_large_cave_depth (Large cave depth) int -33 -# Deprecated, define and locate cave liquids using biome definitions instead. -# Y of upper limit of lava in large caves. -mgflat_lava_depth (Lava depth) int -256 +# Minimum limit of random number of small caves per mapchunk. +mgflat_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgflat_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgflat_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgflat_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgflat_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 # Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. mgflat_cave_width (Cave width) float 0.09 # Terrain noise threshold for lakes. @@ -1767,20 +1861,33 @@ [*Mapgen Fractal] -# Map generation attributes specific to Mapgen flat. +# Map generation attributes specific to Mapgen Fractal. # 'terrain' enables the generation of non-fractal terrain: # ocean, islands and underground. mgfractal_spflags (Mapgen Fractal specific flags) flags terrain terrain,noterrain # Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. mgfractal_cave_width (Cave width) float 0.09 # Y of upper limit of large caves. mgfractal_large_cave_depth (Large cave depth) int -33 -# Deprecated, define and locate cave liquids using biome definitions instead. -# Y of upper limit of lava in large caves. -mgfractal_lava_depth (Lava depth) int -256 +# Minimum limit of random number of small caves per mapchunk. +mgfractal_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgfractal_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgfractal_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgfractal_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgfractal_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 # Lower Y limit of dungeons. mgfractal_dungeon_ymin (Dungeon minimum Y) int -31000 @@ -1789,24 +1896,24 @@ mgfractal_dungeon_ymax (Dungeon maximum Y) int 31000 # Selects one of 18 fractal types. -# 1 = 4D "Roundy" mandelbrot set. -# 2 = 4D "Roundy" julia set. -# 3 = 4D "Squarry" mandelbrot set. -# 4 = 4D "Squarry" julia set. -# 5 = 4D "Mandy Cousin" mandelbrot set. -# 6 = 4D "Mandy Cousin" julia set. -# 7 = 4D "Variation" mandelbrot set. -# 8 = 4D "Variation" julia set. -# 9 = 3D "Mandelbrot/Mandelbar" mandelbrot set. -# 10 = 3D "Mandelbrot/Mandelbar" julia set. -# 11 = 3D "Christmas Tree" mandelbrot set. -# 12 = 3D "Christmas Tree" julia set. -# 13 = 3D "Mandelbulb" mandelbrot set. -# 14 = 3D "Mandelbulb" julia set. -# 15 = 3D "Cosine Mandelbulb" mandelbrot set. -# 16 = 3D "Cosine Mandelbulb" julia set. -# 17 = 4D "Mandelbulb" mandelbrot set. -# 18 = 4D "Mandelbulb" julia set. +# 1 = 4D "Roundy" Mandelbrot set. +# 2 = 4D "Roundy" Julia set. +# 3 = 4D "Squarry" Mandelbrot set. +# 4 = 4D "Squarry" Julia set. +# 5 = 4D "Mandy Cousin" Mandelbrot set. +# 6 = 4D "Mandy Cousin" Julia set. +# 7 = 4D "Variation" Mandelbrot set. +# 8 = 4D "Variation" Julia set. +# 9 = 3D "Mandelbrot/Mandelbar" Mandelbrot set. +# 10 = 3D "Mandelbrot/Mandelbar" Julia set. +# 11 = 3D "Christmas Tree" Mandelbrot set. +# 12 = 3D "Christmas Tree" Julia set. +# 13 = 3D "Mandelbulb" Mandelbrot set. +# 14 = 3D "Mandelbulb" Julia set. +# 15 = 3D "Cosine Mandelbulb" Mandelbrot set. +# 16 = 3D "Cosine Mandelbulb" Julia set. +# 17 = 4D "Mandelbulb" Mandelbrot set. +# 18 = 4D "Mandelbulb" Julia set. mgfractal_fractal (Fractal type) int 1 1 18 # Iterations of the recursive function. @@ -1828,7 +1935,7 @@ # Can be used to move a desired point to (0, 0) to create a # suitable spawn point, or to allow 'zooming in' on a desired # point by increasing 'scale'. -# The default is tuned for a suitable spawn point for mandelbrot +# The default is tuned for a suitable spawn point for Mandelbrot # sets with default parameters, it may need altering in other # situations. # Range roughly -2 to 2. Multiply by 'scale' for offset in nodes. @@ -1901,9 +2008,20 @@ # Depth below which you'll find large caves. mgvalleys_large_cave_depth (Large cave depth) int -33 -# Deprecated, define and locate cave liquids using biome definitions instead. -# Y of upper limit of lava in large caves. -mgvalleys_lava_depth (Lava depth) int 1 +# Minimum limit of random number of small caves per mapchunk. +mgvalleys_small_cave_num_min (Small cave minimum number) int 0 0 256 + +# Maximum limit of random number of small caves per mapchunk. +mgvalleys_small_cave_num_max (Small cave maximum number) int 0 0 256 + +# Minimum limit of random number of large caves per mapchunk. +mgvalleys_large_cave_num_min (Large cave minimum number) int 0 0 64 + +# Maximum limit of random number of large caves per mapchunk. +mgvalleys_large_cave_num_max (Large cave maximum number) int 2 0 64 + +# Proportion of large caves that contain liquid. +mgvalleys_large_cave_flooded (Large cave proportion flooded) float 0.5 0.0 1.0 # Depth below which you'll find giant caverns. mgvalleys_cavern_limit (Cavern upper limit) int -256 @@ -1921,6 +2039,8 @@ mgvalleys_river_size (River size) int 5 # Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. mgvalleys_cave_width (Cave width) float 0.09 # Lower Y limit of dungeons. diff -Nru minetest-5.1.1/.clang-tidy minetest-5.2.0/.clang-tidy --- minetest-5.1.1/.clang-tidy 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/.clang-tidy 2020-04-05 17:53:12.000000000 +0000 @@ -1,4 +1,5 @@ -Checks: '-*,modernize-use-emplace,modernize-use-default-member-init,modernize-use-equals-delete,modernize-use-equals-default,modernize-return-braced-init-list,modernize-loop-convert,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-string-compare,misc-inefficient-algorithm,misc-inaccurate-erase,misc-incorrect-roundings,misc-unconventional-assign-operator,bugprone-suspicious-memset-usage,performance-*' +Checks: '-*,modernize-use-emplace,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,performance-*' +WarningsAsErrors: '-*,modernize-use-emplace,performance-type-promotion-in-math-fn,performance-faster-string-find,performance-implicit-cast-in-loop' CheckOptions: - - key: modernize-use-default-member-init.UseAssignment - value: True + - key: performance-unnecessary-value-param.AllowedTypes + value: v[23]f;v[23][su](16|32) diff -Nru minetest-5.1.1/client/shaders/nodes_shader/opengl_vertex.glsl minetest-5.2.0/client/shaders/nodes_shader/opengl_vertex.glsl --- minetest-5.1.1/client/shaders/nodes_shader/opengl_vertex.glsl 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/client/shaders/nodes_shader/opengl_vertex.glsl 2020-04-05 17:53:12.000000000 +0000 @@ -46,6 +46,42 @@ return smoothCurve(triangleWave(x)) * 2.0 - 1.0; } +// OpenGL < 4.3 does not support continued preprocessor lines +#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER + +// +// Simple, fast noise function. +// See: https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 +// +vec4 perm(vec4 x) +{ + return mod(((x * 34.0) + 1.0) * x, 289.0); +} + +float snoise(vec3 p) +{ + vec3 a = floor(p); + vec3 d = p - a; + d = d * d * (3.0 - 2.0 * d); + + vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0); + vec4 k1 = perm(b.xyxy); + vec4 k2 = perm(k1.xyxy + b.zzww); + + vec4 c = k2 + a.zzzz; + vec4 k3 = perm(c); + vec4 k4 = perm(c + 1.0); + + vec4 o1 = fract(k3 * (1.0 / 41.0)); + vec4 o2 = fract(k4 * (1.0 / 41.0)); + + vec4 o3 = o2 * d.z + o1 * (1.0 - d.z); + vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x); + + return o4.y * d.y + o4.x * (1.0 - d.y); +} + +#endif void main(void) { @@ -65,7 +101,8 @@ float disp_x; float disp_z; -#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS) +#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || \ + (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS) vec4 pos2 = mWorld * gl_Vertex; float tOffset = (pos2.x + pos2.y) * 0.001 + pos2.z * 0.002; disp_x = (smoothTriangleWave(animationTimer * 23.0 + tOffset) + @@ -75,12 +112,21 @@ smoothTriangleWave(animationTimer * 13.0 + tOffset)) * 0.5; #endif + worldPosition = (mWorld * gl_Vertex).xyz; +// OpenGL < 4.3 does not support continued preprocessor lines #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER + // Generate waves with Perlin-type noise. + // The constants are calibrated such that they roughly + // correspond to the old sine waves. vec4 pos = gl_Vertex; - pos.y -= 2.0; - float posYbuf = (pos.z / WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH); - pos.y -= sin(posYbuf) * WATER_WAVE_HEIGHT + sin(posYbuf / 7.0) * WATER_WAVE_HEIGHT; + vec3 wavePos = worldPosition + cameraOffset; + // The waves are slightly compressed along the z-axis to get + // wave-fronts along the x-axis. + wavePos.x /= WATER_WAVE_LENGTH * 3; + wavePos.z /= WATER_WAVE_LENGTH * 2; + wavePos.z += animationTimer * WATER_WAVE_SPEED * 10; + pos.y += (snoise(wavePos) - 1) * WATER_WAVE_HEIGHT * 5; gl_Position = mWorldViewProj * pos; #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES vec4 pos = gl_Vertex; @@ -101,7 +147,6 @@ vPosition = gl_Position.xyz; - worldPosition = (mWorld * gl_Vertex).xyz; // Don't generate heightmaps when too far from the eye float dist = distance (vec3(0.0, 0.0, 0.0), vPosition); @@ -141,12 +186,12 @@ color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb + nightRatio * artificialLight.rgb) * 2; color.a = 1; - + // 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; color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) + 0.07 * brightness); - + gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0); } diff -Nru minetest-5.1.1/client/shaders/object_shader/opengl_fragment.glsl minetest-5.2.0/client/shaders/object_shader/opengl_fragment.glsl --- minetest-5.1.1/client/shaders/object_shader/opengl_fragment.glsl 1970-01-01 00:00:00.000000000 +0000 +++ minetest-5.2.0/client/shaders/object_shader/opengl_fragment.glsl 2020-04-05 17:53:12.000000000 +0000 @@ -0,0 +1,131 @@ +uniform sampler2D baseTexture; +uniform sampler2D normalTexture; +uniform sampler2D textureFlags; + +uniform vec4 emissiveColor; +uniform vec4 skyBgColor; +uniform float fogDistance; +uniform vec3 eyePosition; + +varying vec3 vNormal; +varying vec3 vPosition; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 lightVec; +varying float vIDiff; + +bool normalTexturePresent = false; +bool texTileableHorizontal = false; +bool texTileableVertical = false; +bool texSeamless = false; + +const float e = 2.718281828459; +const float BS = 10.0; +const float fogStart = FOG_START; +const float fogShadingParameter = 1 / ( 1 - fogStart); + +void get_texture_flags() +{ + vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0)); + if (flags.r > 0.5) { + normalTexturePresent = true; + } + if (flags.g > 0.5) { + texTileableHorizontal = true; + } + if (flags.b > 0.5) { + texTileableVertical = true; + } + if (texTileableHorizontal && texTileableVertical) { + texSeamless = true; + } +} + +float intensity(vec3 color) +{ + return (color.r + color.g + color.b) / 3.0; +} + +float get_rgb_height(vec2 uv) +{ + if (texSeamless) { + return intensity(texture2D(baseTexture, uv).rgb); + } else { + return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb); + } +} + +vec4 get_normal_map(vec2 uv) +{ + vec4 bump = texture2D(normalTexture, uv).rgba; + bump.xyz = normalize(bump.xyz * 2.0 - 1.0); + return bump; +} + +void main(void) +{ + vec3 color; + vec4 bump; + vec2 uv = gl_TexCoord[0].st; + bool use_normalmap = false; + get_texture_flags(); + +#if USE_NORMALMAPS == 1 + if (normalTexturePresent) { + bump = get_normal_map(uv); + use_normalmap = true; + } +#endif + +#if GENERATE_NORMALMAPS == 1 + if (normalTexturePresent == false) { + float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP)); + float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP)); + float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP)); + float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y)); + float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP)); + float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP)); + float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP)); + float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y)); + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0); + use_normalmap = true; + } +#endif + + vec4 base = texture2D(baseTexture, uv).rgba; + +#ifdef ENABLE_BUMPMAPPING + if (use_normalmap) { + vec3 L = normalize(lightVec); + vec3 E = normalize(eyeVec); + float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0); + float diffuse = dot(-E,bump.xyz); + color = (diffuse + 0.1 * specular) * base.rgb; + } else { + color = base.rgb; + } +#else + color = base.rgb; +#endif + + vec4 col = vec4(color.rgb, base.a); + + col.rgb *= emissiveColor.rgb * vIDiff; + // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?), + // the fog will only be rendered correctly if the last operation before the + // clamp() is an addition. Else, the clamp() seems to be ignored. + // E.g. the following won't work: + // float clarity = clamp(fogShadingParameter + // * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0); + // As additions usually come for free following a multiplication, the new formula + // should be more efficient as well. + // Note: clarity = (1 - fogginess) + float clarity = clamp(fogShadingParameter + - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0); + col = mix(skyBgColor, col, clarity); + + gl_FragColor = vec4(col.rgb, base.a); +} diff -Nru minetest-5.1.1/client/shaders/object_shader/opengl_vertex.glsl minetest-5.2.0/client/shaders/object_shader/opengl_vertex.glsl --- minetest-5.1.1/client/shaders/object_shader/opengl_vertex.glsl 1970-01-01 00:00:00.000000000 +0000 +++ minetest-5.2.0/client/shaders/object_shader/opengl_vertex.glsl 2020-04-05 17:53:12.000000000 +0000 @@ -0,0 +1,44 @@ +uniform mat4 mWorldViewProj; +uniform mat4 mWorld; + +uniform vec3 eyePosition; +uniform float animationTimer; + +varying vec3 vNormal; +varying vec3 vPosition; +varying vec3 worldPosition; + +varying vec3 eyeVec; +varying vec3 lightVec; +varying float vIDiff; + +const float e = 2.718281828459; +const float BS = 10.0; + +float directional_ambient(vec3 normal) +{ + vec3 v = normal * normal; + + if (normal.y < 0) + return dot(v, vec3(0.670820f, 0.447213f, 0.836660f)); + + return dot(v, vec3(0.670820f, 1.000000f, 0.836660f)); +} + +void main(void) +{ + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_Position = mWorldViewProj * gl_Vertex; + + vPosition = gl_Position.xyz; + vNormal = gl_Normal; + worldPosition = (mWorld * gl_Vertex).xyz; + + vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); + + lightVec = sunPosition - worldPosition; + eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz; + vIDiff = directional_ambient(normalize(gl_Normal)); + + gl_FrontColor = gl_BackColor = gl_Color; +} diff -Nru minetest-5.1.1/clientmods/preview/example.lua minetest-5.2.0/clientmods/preview/example.lua --- minetest-5.1.1/clientmods/preview/example.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/clientmods/preview/example.lua 2020-04-05 17:53:12.000000000 +0000 @@ -1,2 +1,2 @@ print("Loaded example file!, loading more examples") -dofile("preview:examples/first.lua") +dofile(core.get_modpath(core.get_current_modname()) .. "/examples/first.lua") diff -Nru minetest-5.1.1/clientmods/preview/init.lua minetest-5.2.0/clientmods/preview/init.lua --- minetest-5.1.1/clientmods/preview/init.lua 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/clientmods/preview/init.lua 2020-04-05 17:53:12.000000000 +0000 @@ -1,19 +1,27 @@ -local modname = core.get_current_modname() or "??" +local modname = assert(core.get_current_modname()) local modstorage = core.get_mod_storage() local mod_channel -dofile("preview:example.lua") --- This is an example function to ensure it's working properly, should be removed before merge +dofile(core.get_modpath(modname) .. "example.lua") + core.register_on_shutdown(function() print("[PREVIEW] shutdown client") end) local id = nil -local server_info = core.get_server_info() -print("Server version: " .. server_info.protocol_version) -print("Server ip: " .. server_info.ip) -print("Server address: " .. server_info.address) -print("Server port: " .. server_info.port) +do + local server_info = core.get_server_info() + print("Server version: " .. server_info.protocol_version) + print("Server ip: " .. server_info.ip) + print("Server address: " .. server_info.address) + print("Server port: " .. server_info.port) + + print("CSM restrictions: " .. dump(core.get_csm_restrictions())) + + local l1, l2 = core.get_language() + print("Configured language: " .. l1 .. " / " .. l2) +end + mod_channel = core.mod_channel_join("experimental_preview") core.after(4, function() @@ -65,6 +73,26 @@ print("The local player used an item!") print("pointed_thing :" .. dump(pointed_thing)) print("item = " .. itemstack:get_name()) + + if not itemstack:is_empty() then + return false + end + + local pos = vector.add(core.localplayer:get_pos(), core.camera:get_offset()) + local pos2 = vector.add(pos, vector.multiply(core.camera:get_look_dir(), 100)) + + local rc = core.raycast(pos, pos2) + local i = rc:next() + print("[PREVIEW] raycast next: " .. dump(i)) + if i then + print("[PREVIEW] line of sight: " .. (core.line_of_sight(pos, i.above) and "yes" or "no")) + + local n1 = core.find_nodes_in_area(pos, i.under, {"default:stone"}) + local n2 = core.find_nodes_in_area_under_air(pos, i.under, {"default:stone"}) + print(("[PREVIEW] found %s nodes, %s nodes under air"):format( + n1 and #n1 or "?", n2 and #n2 or "?")) + end + return false end) @@ -91,11 +119,6 @@ end) -- This is an example function to ensure it's working properly, should be removed before merge -core.register_globalstep(function(dtime) - -- print("[PREVIEW] globalstep " .. dtime) -end) - --- This is an example function to ensure it's working properly, should be removed before merge core.register_chatcommand("dump", { func = function(param) return true, dump(_G) @@ -143,8 +166,7 @@ core.ui.minimap:show() end - print("[PREVIEW] Day count: " .. core.get_day_count() .. - " time of day " .. core.get_timeofday()) + print("[PREVIEW] Time of day " .. core.get_timeofday()) print("[PREVIEW] Node level: " .. core.get_node_level({x=0, y=20, z=0}) .. " max level " .. core.get_node_max_level({x=0, y=20, z=0})) diff -Nru minetest-5.1.1/CMakeLists.txt minetest-5.2.0/CMakeLists.txt --- minetest-5.1.1/CMakeLists.txt 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/CMakeLists.txt 2020-04-05 17:53:12.000000000 +0000 @@ -16,8 +16,8 @@ # Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing set(VERSION_MAJOR 5) -set(VERSION_MINOR 1) -set(VERSION_PATCH 1) +set(VERSION_MINOR 2) +set(VERSION_PATCH 0) set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string") # Change to false for releases @@ -164,24 +164,24 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/textures/texture_packs_here.txt" DESTINATION "${SHAREDIR}/textures") endif() -install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game" DESTINATION "${SHAREDIR}/games/" +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game" DESTINATION "${SHAREDIR}/games/" COMPONENT "SUBGAME_MINETEST_GAME" OPTIONAL PATTERN ".git*" EXCLUDE ) -install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games/" +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games/" COMPONENT "SUBGAME_MINIMAL" OPTIONAL PATTERN ".git*" EXCLUDE ) if(BUILD_CLIENT) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/shaders" DESTINATION "${SHAREDIR}/client") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base") + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fonts" DESTINATION "${SHAREDIR}") if(RUN_IN_PLACE) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/clientmods" DESTINATION "${SHAREDIR}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/serverlist" DESTINATION "${SHAREDIR}/client") endif() endif() -install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fonts" DESTINATION "${SHAREDIR}") - install(FILES "README.md" DESTINATION "${DOCDIR}" COMPONENT "Docs") install(FILES "doc/lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") +install(FILES "doc/client_lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") install(FILES "doc/menu_lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") install(FILES "doc/texture_packs.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") install(FILES "doc/world_format.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs") @@ -284,12 +284,12 @@ set(CPACK_CREATE_DESKTOP_LINKS ${PROJECT_NAME}) set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/misc/minetest-icon.ico") - # Supported languages can be found at + # Supported languages can be found at # http://wixtoolset.org/documentation/manual/v3/wixui/wixui_localization.html #set(CPACK_WIX_CULTURES "ar-SA,bg-BG,ca-ES,hr-HR,cs-CZ,da-DK,nl-NL,en-US,et-EE,fi-FI,fr-FR,de-DE") set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/misc/CPACK_WIX_UI_BANNER.BMP") set(CPACK_WIX_UI_DIALOG "${CMAKE_CURRENT_SOURCE_DIR}/misc/CPACK_WIX_UI_DIALOG.BMP") - + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/doc/lgpl-2.1.txt") # The correct way would be to include both x32 and x64 into one installer @@ -325,3 +325,4 @@ COMMENT "Generating API documentation with Doxygen" VERBATIM ) endif() + diff -Nru minetest-5.1.1/debian/changelog minetest-5.2.0/debian/changelog --- minetest-5.1.1/debian/changelog 2020-01-25 01:48:55.000000000 +0000 +++ minetest-5.2.0/debian/changelog 2020-04-05 17:53:20.000000000 +0000 @@ -1,8 +1,8 @@ -minetest (5.1.1-ppa0~ubuntu20.04.1) focal; urgency=low +minetest (5.2.0-ppa0~ubuntu20.04.1) focal; urgency=low * Auto build. - -- est31 Sat, 25 Jan 2020 01:48:55 +0000 + -- rubenwardy Sun, 05 Apr 2020 17:53:20 +0000 minetest (0.0-0) UNRELEASED; urgency=medium diff -Nru minetest-5.1.1/debian/copyright minetest-5.2.0/debian/copyright --- minetest-5.1.1/debian/copyright 2020-01-25 01:48:49.000000000 +0000 +++ minetest-5.2.0/debian/copyright 2020-04-05 17:53:14.000000000 +0000 @@ -3,11 +3,11 @@ Source: Files: * -Copyright: 2010-2012 Perttu Ahola (celeron55) -License: GPL-2.0+ +Copyright: 2010-2020 Perttu Ahola (celeron55) +License: LGPL-2.1+ Files: games/*/mods/*/textures/* games/*/mods/*/sounds/* -Copyright: 2010-2012 Perttu Ahola (celeron55) +Copyright: 2010-2020 Perttu Ahola (celeron55) License: CC-BY-SA-3.0 Files: debian/* @@ -32,6 +32,25 @@ On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + +License: LGPL-2.1+ + This package 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 package 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 package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + On Debian systems, the complete text of the GNU Lesser General + Public License can be found in `/usr/share/common-licenses/LGPL-2.1'. + License: CC-BY-SA-3.0 This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this license, visit diff -Nru minetest-5.1.1/debian/git-build-recipe.manifest minetest-5.2.0/debian/git-build-recipe.manifest --- minetest-5.1.1/debian/git-build-recipe.manifest 2020-01-25 01:48:55.000000000 +0000 +++ minetest-5.2.0/debian/git-build-recipe.manifest 2020-04-05 17:53:20.000000000 +0000 @@ -1,4 +1,4 @@ -# git-build-recipe format 0.4 deb-version 5.1.1-ppa0 -lp:minetest-c55 git-commit:c02f13d33f87e030e89a63767f5f96e03fedc6fe -nest packaging lp:~minetestdevs/minetest-c55/+git/packaging debian git-commit:6e1a0eca337bac849430fb6b6ba9e45f16ff7246 -nest minetest_game lp:~minetestdevs/minetest-c55/+git/upstream_game games/minetest_game git-commit:93a49f082c0053ae484eeb55cad47677471e03e8 +# git-build-recipe format 0.4 deb-version 5.2.0-ppa0 +lp:minetest-c55 git-commit:24147d99c00b3b7677a2c2f8f47e036a6371d03b +nest packaging lp:~minetestdevs/minetest-c55/+git/packaging debian git-commit:0bc3635323bdd991ba507ff4d7fd7e8f97e210c8 +nest minetest_game lp:~minetestdevs/minetest-c55/+git/upstream_game games/minetest_game git-commit:8863527bb62c0cb3bf19d6d2acf6ecb817e61cc2 diff -Nru minetest-5.1.1/debian/rules minetest-5.2.0/debian/rules --- minetest-5.1.1/debian/rules 2020-01-25 01:48:49.000000000 +0000 +++ minetest-5.2.0/debian/rules 2020-04-05 17:53:14.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/make -f override_dh_auto_configure: - dh_auto_configure -- -DENABLE_CURSES=1 -DENABLE_LEVELDB=1 -DENABLE_FREETYPE=1 -DENABLE_GETTEXT=1 + dh_auto_configure -- -DENABLE_CURSES=1 -DENABLE_LEVELDB=1 -DENABLE_FREETYPE=1 -DENABLE_GETTEXT=1 -DCMAKE_BUILD_TYPE=Release %: dh $@ diff -Nru minetest-5.1.1/doc/client_lua_api.txt minetest-5.2.0/doc/client_lua_api.txt --- minetest-5.1.1/doc/client_lua_api.txt 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/doc/client_lua_api.txt 2020-04-05 17:53:12.000000000 +0000 @@ -1,4 +1,4 @@ -Minetest Lua Client Modding API Reference 5.1.0 +Minetest Lua Client Modding API Reference 5.2.0 ================================================ * More information at * Developer Wiki: @@ -30,7 +30,7 @@ Mods are loaded during client startup from the mod load paths by running the `init.lua` scripts in a shared environment. -In order to load client-side mods in a world, the following conditions need to be satisfied: +In order to load client-side mods, the following conditions need to be satisfied: 1) `$path_user/minetest.conf` contains the setting `enable_client_modding = true` @@ -43,14 +43,10 @@ Paths ----- * `RUN_IN_PLACE=1` (Windows release, local build) - * `$path_user`: - * Linux: `` - * Windows: `` - * `$path_share` - * Linux: `` - * Windows: `` + * `$path_user`: `` + * `$path_share`: `` * `RUN_IN_PLACE=0`: (Linux release) - * `$path_share` + * `$path_share`: * Linux: `/usr/share/minetest` * Windows: `/minetest-0.4.x` * `$path_user`: @@ -75,7 +71,6 @@ Modpack support ---------------- -**NOTE: Not implemented yet.** Mods can be put in a subdirectory, if the parent directory, which otherwise should be a mod, contains a file named `modpack.conf`. @@ -90,30 +85,36 @@ clientmods ├── modname - | ├── depends.txt - | ├── init.lua + │   ├── mod.conf + │   ├── init.lua └── another ### modname + The location of this directory. -### depends.txt -List of mods that have to be loaded before loading this mod. +### mod.conf + +An (optional) settings file that provides meta information about the mod. -A single line contains a single modname. +* `name`: The mod name. Allows Minetest to determine the mod name even if the + folder is wrongly named. +* `description`: Description of mod to be shown in the Mods tab of the main + menu. +* `depends`: A comma separated list of dependencies. These are mods that must be + loaded before this mod. +* `optional_depends`: A comma separated list of optional dependencies. + Like a dependency, but no error if the mod doesn't exist. -Optional dependencies can be defined by appending a question mark -to a single modname. Their meaning is that if the specified mod -is missing, that does not prevent this mod from being loaded. +### `init.lua` -### init.lua The main Lua script. Running this script should register everything it wants to register. Subsequent execution depends on minetest calling the registered callbacks. -### `sounds` -Media files (sounds) that will be transferred to the -client and will be available for use by the mod. +**NOTE**: Client mods currently can't provide and textures, sounds or models by +themselves. Any media referenced in function calls must already be loaded +(provided by mods that exist on the server). Naming convention for registered textual names ---------------------------------------------- @@ -142,7 +143,7 @@ Sounds ------ -**NOTE: max_hear_distance and connecting to objects is not implemented.** +**NOTE: Connecting sounds to objects is not implemented.** Only Ogg Vorbis files are supported. @@ -182,13 +183,11 @@ { pos = {x = 1, y = 2, z = 3}, gain = 1.0, -- default - max_hear_distance = 32, -- default, uses an euclidean metric } -- Play connected to an object, looped { object = , gain = 1.0, -- default - max_hear_distance = 32, -- default, uses an euclidean metric loop = true, } @@ -631,7 +630,13 @@ ### Utilities * `minetest.get_current_modname()`: returns the currently loading mod's name, when we are loading a mod -* `minetest.get_language()`: returns the currently set gettext language. +* `minetest.get_modpath(modname)`: returns virtual path of given mod including + the trailing separator. This is useful to load additional Lua files + contained in your mod: + e.g. `dofile(minetest.get_modpath(minetest.get_current_modname()) .. "stuff.lua")` +* `minetest.get_language()`: returns two strings + * the current gettext locale + * the current language code (the same as used for client-side translations) * `minetest.get_version()`: returns a table containing components of the engine version. Components: * `project`: Name of the project, eg, "Minetest" @@ -646,6 +651,11 @@ * `minetest.sha1(data, [raw])`: returns the sha1 hash of data * `data`: string of data to hash * `raw`: return raw bytes instead of hex digits, default: false +* `minetest.get_csm_restrictions()`: returns a table of `Flags` indicating the + restrictions applied to the current mod. + * If a flag in this table is set to true, the feature is RESTRICTED. + * Possible flags: `load_client_mods`, `chat_messages`, `read_itemdefs`, + `read_nodedefs`, `lookup_nodes`, `read_playerinfo` ### Logging * `minetest.debug(...)` @@ -731,8 +741,6 @@ * Optional: Variable number of arguments that are passed to `func` * `minetest.get_us_time()` * Returns time with microsecond precision. May not return wall time. -* `minetest.get_day_count()` - * Returns number days elapsed since world was created, accounting for time changes. * `minetest.get_timeofday()` * Returns the time of day: `0` for midnight, `0.5` for midday @@ -741,11 +749,46 @@ * Returns the node at the given position as table in the format `{name="node_name", param1=0, param2=0}`, returns `nil` for unloaded areas or flavor limited areas. +* `minetest.get_node_light(pos, timeofday)` + * Gets the light value at the given position. Note that the light value + "inside" the node at the given position is returned, so you usually want + to get the light value of a neighbor. + * `pos`: The position where to measure the light. + * `timeofday`: `nil` for current time, `0` for night, `0.5` for day + * Returns a number between `0` and `15` or `nil` * `minetest.find_node_near(pos, radius, nodenames, [search_center])`: returns pos or `nil` * `radius`: using a maximum metric * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` * `search_center` is an optional boolean (default: `false`) If true `pos` is also checked for the nodes +* `minetest.find_nodes_in_area(pos1, pos2, nodenames)`: returns a list of + positions. + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * First return value: Table with all node positions + * Second return value: Table with the count of each node with the node name + as index. + * Area volume is limited to 4,096,000 nodes +* `minetest.find_nodes_in_area_under_air(pos1, pos2, nodenames)`: returns a + list of positions. + * `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"` + * Return value: Table with all node positions with a node air above + * Area volume is limited to 4,096,000 nodes +* `minetest.line_of_sight(pos1, pos2)`: returns `boolean, pos` + * Checks if there is anything other than air between pos1 and pos2. + * Returns false if something is blocking the sight. + * Returns the position of the blocking node when `false` + * `pos1`: First position + * `pos2`: Second position +* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast` + * Creates a `Raycast` object. + * `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`. + +* `minetest.find_nodes_with_meta(pos1, pos2)` + * Get a table of positions of nodes that have metadata within a region + {pos1, pos2}. * `minetest.get_meta(pos)` * Get a `NodeMetaRef` at that position * `minetest.get_node_level(pos)` @@ -1072,6 +1115,32 @@ * `fields`: key-value storage * `inventory`: `{list1 = {}, ...}}` +### `Raycast` + +A raycast on the map. It works with selection boxes. +Can be used as an iterator in a for loop as: + + local ray = Raycast(...) + for pointed_thing in ray do + ... + end + +The map is loaded as the ray advances. If the map is modified after the +`Raycast` is created, the changes may or may not have an effect on the object. + +It can be created via `Raycast(pos1, pos2, objects, liquids)` or +`minetest.raycast(pos1, pos2, objects, liquids)` where: + +* `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. + +#### Methods + +* `next()`: returns a `pointed_thing` with exact pointing location + * Returns the next thing pointed by the ray or nil. + ----------------- ### Definitions * `minetest.get_node_def(nodename)` diff -Nru minetest-5.1.1/doc/lua_api.txt minetest-5.2.0/doc/lua_api.txt --- minetest-5.1.1/doc/lua_api.txt 2020-01-25 01:48:47.000000000 +0000 +++ minetest-5.2.0/doc/lua_api.txt 2020-04-05 17:53:12.000000000 +0000 @@ -826,7 +826,7 @@ gain = 1.0, -- default loop = true, } - -- Play in a location + -- Play at a location { pos = {x = 1, y = 2, z = 3}, gain = 1.0, -- default @@ -839,34 +839,58 @@ max_hear_distance = 32, -- default, uses an euclidean metric loop = true, } + -- Play at a location, heard by anyone *but* the given player + { + pos = {x = 32, y = 0, z = 100}, + max_hear_distance = 40, + exclude_player = name, + } Looped sounds must either be connected to an object or played locationless to -one player using `to_player = name,`. +one player using `to_player = name`. A positional sound will only be heard by players that are within `max_hear_distance` of the sound position, at the start of the sound. +`exclude_player = name` can be applied to locationless, positional and object- +bound sounds to exclude a single player from hearing them. + `SimpleSoundSpec` ----------------- -* e.g. `""` -* e.g. `"default_place_node"` -* e.g. `{}` -* e.g. `{name = "default_place_node"}` -* e.g. `{name = "default_place_node", gain = 1.0}` -* e.g. `{name = "default_place_node", gain = 1.0, pitch = 1.0}` +Specifies a sound name, gain (=volume) and pitch. +This is either a string or a table. + +In string form, you just specify the sound name or +the empty string for no sound. +Table form has the following fields: + +* `name`: Sound name +* `gain`: Volume (`1.0` = 100%) +* `pitch`: Pitch (`1.0` = 100%) + +`gain` and `pitch` are optional and default to `1.0`. + +Examples: + +* `""`: No sound +* `{}`: No sound +* `"default_place_node"`: Play e.g. `default_place_node.ogg` +* `{name = "default_place_node"}`: Same as above +* `{name = "default_place_node", gain = 0.5}`: 50% volume +* `{name = "default_place_node", gain = 0.9, pitch = 1.1}`: 90% volume, 110% pitch Special sound files ------------------- These sound files are played back by the engine if provided. - * `main_menu`: Looped sound in the main menu (gain = 1.0) * `player_damage`: Played when the local player takes damage (gain = 0.5) * `player_falling_damage`: Played when the local player takes damage by falling (gain = 0.5) - + * `default_dig_`: Default node digging sound + (see node sound definition for details) Registered definitions ====================== @@ -924,7 +948,8 @@ The functions of `param1` and `param2` are determined by certain fields in the node definition. -`param1` is reserved for the engine when `paramtype != "none"`: +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 @@ -941,19 +966,27 @@ * mesh * plantlike * plantlike_rooted - -`param2` is reserved for the engine when any of these are used: - -* `liquidtype = "flowing"` - * The level and some flags of the liquid is stored in `param2` -* `drawtype = "flowingliquid"` - * The drawn liquid level is read from `param2` -* `drawtype = "torchlike"` -* `drawtype = "signlike"` +* `paramtype = "none"` + * `param1` will not be used by the engine and can be used to store + an arbitrary value + +The function of `param2` is determined by `paramtype2` in node definition. +`param2` is reserved for the engine when `paramtype2 != "none"`. + +* `paramtype2 = "flowingliquid"` + * Used by `drawtype = "flowingliquid"` and `liquidtype = "flowing"` + * The liquid level and a flag of the liquid are stored in `param2` + * Bits 0-2: Liquid level (0-7). The higher, the more liquid is in this node + * Bit 3: If set, liquid is flowing downwards (no graphical effect) * `paramtype2 = "wallmounted"` - * The rotation of the node is stored in `param2`. You can make this value - by using `minetest.dir_to_wallmounted()`. + * Supported drawtypes: "torchlike", "signlike", "normal", "nodebox", "mesh" + * The rotation of the node is stored in `param2` + * You can make this value by using `minetest.dir_to_wallmounted()` + * Values range 0 - 5 + * The value denotes at which direction the node is "mounted": + 0 = y+, 1 = y-, 2 = x+, 3 = x-, 4 = z+, 5 = z- * `paramtype2 = "facedir"` + * Supported drawtypes: "normal", "nodebox", "mesh" * The rotation of the node is stored in `param2`. Furnaces and chests are rotated this way. Can be made by using `minetest.dir_to_facedir()`. * Values range 0 - 23 @@ -972,13 +1005,13 @@ * The height of the 'plantlike' section is stored in `param2`. * The height is (`param2` / 16) nodes. * `paramtype2 = "degrotate"` - * Only valid for "plantlike". The rotation of the node is stored in + * Only valid for "plantlike" drawtype. The rotation of the node is stored in `param2`. * Values range 0 - 179. The value stored in `param2` is multiplied by two to get the actual rotation in degrees of the node. * `paramtype2 = "meshoptions"` - * Only valid for "plantlike". The value of `param2` becomes a bitfield which - can be used to change how the client draws plantlike nodes. + * Only valid for "plantlike" drawtype. The value of `param2` becomes a + bitfield which can be used to change how the client draws plantlike nodes. * Bits 0, 1 and 2 form a mesh selector. Currently the following meshes are choosable: * 0 = a "x" shaped plant (ordinary plant) @@ -1010,6 +1043,9 @@ * `param2` values 0-63 define 64 levels of internal liquid, 0 being empty and 63 being full. * Liquid texture is defined using `special_tiles = {"modname_tilename.png"}` +* `paramtype2 = "none"` + * `param2` will not be used by the engine and can be used to store + an arbitrary value Nodes can also contain extra data. See [Node Metadata]. @@ -1260,6 +1296,11 @@ **Note**: `offset` _will_ adapt to screen DPI as well as user defined scaling factor! +The `z_index` field specifies the order of HUD elements from back to front. +Lower z-index elements are displayed behind higher z-index elements. Elements +with same z-index are displayed in an arbitrary order. Default 0. +Supports negative values. + Below are the specific uses for fields in each type; fields not listed for that type are ignored. @@ -1476,7 +1517,8 @@ ----- Groups are stored in a table, having the group names with keys and the -group ratings as values. For example: +group ratings as values. Group ratings are integer values within the +range [-32767, 32767]. For example: -- Default dirt groups = {crumbly=3, soil=1} @@ -1923,6 +1965,9 @@ use `minetest.formspec_escape`. For coloured text you can use `minetest.colorize`. +Since formspec version 3, elements drawn in the order they are defined. All +background elements are drawn before all other elements. + **WARNING**: do _not_ use a element name starting with `key_`; those names are reserved to pass key press events to formspec! @@ -2075,28 +2120,47 @@ ### `tooltip[;;;]` * Adds tooltip for an element -* `` tooltip background color as `ColorString` (optional) -* `` tooltip font color as `ColorString` (optional) +* `bgcolor` tooltip background color as `ColorString` (optional) +* `fontcolor` tooltip font color as `ColorString` (optional) ### `tooltip[,;,;;;]` * Adds tooltip for an area. Other tooltips will take priority when present. -* `` tooltip background color as `ColorString` (optional) -* `` tooltip font color as `ColorString` (optional) +* `bgcolor` tooltip background color as `ColorString` (optional) +* `fontcolor` tooltip font color as `ColorString` (optional) ### `image[,;,;]` * Show an image +### `animated_image[,;,;;;;;]` + +* Show an animated image. The image is drawn like a "vertical_frames" tile + animation (See [Tile animation definition]), but uses a frame count/duration + for simplicity +* `name`: Element name to send when an event occurs. The event value is the index of the current frame. +* `texture name`: The image to use. +* `frame count`: The number of frames animating the image. +* `frame duration`: Milliseconds between each frame. `0` means the frames don't advance. +* `frame start` (Optional): The index of the frame to start on. Default `1`. + ### `item_image[,;,;]` * Show an inventory image of registered item/node -### `bgcolor[;]` +### `bgcolor[;;]` -* Sets background color of formspec as `ColorString` -* If `true`, a fullscreen background is drawn and the color is ignored - (does not affect the size of the formspec) +* Sets background color of formspec. +* `bgcolor` and `fbgcolor` (optional) are `ColorString`s, they define the color + of the non-fullscreen and the fullscreen background. +* `fullscreen` (optional) can be one of the following: + * `false`: Only the non-fullscreen background color is drawn. (default) + * `true`: Only the fullscreen background color is drawn. + * `both`: The non-fullscreen and the fullscreen background color are drawn. + * `neither`: No background color is drawn. +* Note: Leave a parameter empty to not modify the value. +* Note: `fbgcolor`, leaving parameters empty and values for `fullscreen` that + are not bools are only available since formspec version 3. ### `background[,;,;]` @@ -2189,8 +2253,14 @@ half a coordinate. With the old system, newlines are spaced 2/5 of an inventory slot. -### `vertlabel[,;